用Java DIY 函数式方法—— flatmap

本文是 用Java DIY 函数式方法—— map 续篇, 解决如何使用java实现函数式方法-flatmap。

注意

  • 不适合对函数式一点基础都没有的读者
  • DIY实现不是完美的,仅仅是用实例表达函数式方法的理解
  • 这个系列文章不是分析java 8 stream中的方法源码,而是对java 8 stream特性,结合Kotlin, Rxjava之类的理解, 使用纯java的方式实现类似的函数式方法。
  • 需要对java 中的泛型以及Collection有了解
  • 会用到java 8 lambda表达式
  • 要实际代码验证,需要 jdk 1.8

讲解的模式如下:

  • 给出某个场景
  • 使用 java 8
  • 使用DIY 函数实现

那就进入主题吧: 用Java DIY 函数式方法——flatmap

DIY 函数式方法flatmap

作用: T -> Collection<R> 注意,这是DIY实现理解,Kotlin,java 8 stream各有自己的集合表达

/** 需求:
* 给定 1 个 Integer集合[1,2,3,4,5]
* 将该集合转换为String类型集合["1a", "1b", "2a", "2b", "3a", "3b", "4a","4b", "5a", "5b"]
* 思路: [1,2,3,4,5] -> ["1a", "1b"], ["2a", "2b"], ["3a", "3b"], ["4a","4b"], ["5a", "5b"]
* -> ["1a", "1b", "2a", "2b", "3a", "3b", "4a","4b", "5a", "5b"]
*/

分析: map能解决的是 T -> R的变化, 上述需求有点特别,需要将 [1, 2, 3, 4, 5] 其中的每一个都要添加 "a", "b", 然后把他们整合成一个集合。
要是只能使用map实现,也可以, 可行思路是, 如有好的map思路,请留言!!!

  • [1,2,3,4,5] -> ["1a", "2a", "3a", "4a", "5a"]
  • [1,2,3,4,5] -> ["1b", "2b", "3b", "4b", "5b"]
  • 手动合并,还需要排序达到 ["1a", "1b", "2a", "2b", "3a", "3b", "4a","4b", "5a", "5b"]

1. java 8 stream实现

List<Integer> integerList = Arrays.asList(1,2,3,4,5);
integerList.stream()
                .flatMap(new Function<Integer, Stream<String>>() {
                    @Override
                    public Stream<String> apply(Integer integer) {
                        return Arrays.asList(integer + "a", integer + "b").stream();
                    }
                }).forEach( item -> out.print(item + " ") );

说明: 上述一条链式调用,就解决了我们的需求

lamdba表达式,简洁如下:

integerList.stream()
  .flatMap(integer -> Arrays.asList(integer + "a", integer + "b").stream())
  .forEach(item -> out.print(item + " ") );

2. DIY flatmap

在DIY 之前,需要梳理 flatmap的 核心是什么?

T -> Collection<R>

注意:这是DIY flatmap基于Collection实现,Kotlin, java 8 stream各有自己的转换关系!

所以,需要三个东西: 输入 T, 输出 Collection<R>, 映射关系!

public static <T, R> Collection<? super R> flatMap(Collection<? extends T> collection,
                                                Function<T, Collection<R>> function) {
        Collection<? super R> result = new ArrayList<>();//这里仅仅是演示
        for(T item: collection){
            result.addAll(function.call(item));
        }
        return result;
    }

    public interface Function<T, R>{
        R call(T item);//T -> R
    }    

其中: Collection<? super R> 是flatmap返回值类型, Collection<? extends T> 是输入参数的类型
Function<T, Collection<R>> function 是映射关系, T -> Collection<R>

//这里仅仅是演示
Collection<? super R> result = new ArrayList<>();

一直强调 DIY的实现是有局限性的,我这里是在java集合的基础上,而且选用ArrayList作为实际的主体,要是其他数据结构类型,肯定就没法使用, 但是,不影响 讲解flatmap实现的思路!

如上, 使用者,只需要关注 Function 接口的具体实现方法call的设计。

使用方式如下:

List<Integer> integerList = Arrays.asList(1,2,3,4,5);

flatMap(integerList, new Function<Integer, Collection<String>>() {
    @Override
    public Collection<String> call(Integer item) {
        return Arrays.asList(item + "a", item + "b");
    }
}).forEach(item -> out.print(item + " ") );

lambda简化:

flatMap(integerList, integer -> Arrays.asList(integer + "a", integer + "b") )
                .forEach(item -> out.print(item + " "));

其他实例:将三个IntegerList整合为一个List [1], [2,3], [4,5,6] -> [1,2,3,4,5,6]

Collection<List<Integer>> input = Arrays.asList(
                Arrays.asList(1),
                Arrays.asList(2,3),
                Arrays.asList(4, 5, 6));

        flatMap(input, item -> new ArrayList<Integer>(item))
                .forEach(out::println);

小结

理解 T -> Collection<R>,就明白了flatmap的原理了,遇到实际的情况,可以考虑用flatmap实现,体会跟传统的不同之处!
代码上传到 csdn 资源下载

喜欢,用实际点赞支持我吧! 欢迎留言讨论!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容