用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 注意,这是DIY实现理解,Kotlin,java 8 stream各有自己的集合表达

/** 需求:
* 给定 1Integer集合[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
注意:这是DIY flatmap基于Collection实现,Kotlin, java 8 stream各有自己的转换关系!

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

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

//这里仅仅是演示
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,就明白了flatmap的原理了,遇到实际的情况,可以考虑用flatmap实现,体会跟传统的不同之处!
代码上传到 csdn 资源下载

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值