问答

java8-stream-flatMap

作者:admin 2021-07-09 我要评论

下面的代码A处的第一种, 可以正确输出结果如下; B处的int数组类型的就会报告错误: Bad return type in lambda expression: int[] cannot be converted to int 请...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

下面的代码A处的第一种, 可以正确输出结果如下;
B处的int数组类型的就会报告错误:Bad return type in lambda expression: int[] cannot be converted to int
请java8 stream高手指教下为何~

(1, 2)
(1, 4)
(1, 6)
(1, 8)
(1, 10)
(3, 2)
(3, 4)
(3, 6)
(3, 8)
(3, 10)
(5, 2)
(5, 4)
(5, 6)
(5, 8)
(5, 10)
(7, 2)
(7, 4)
(7, 6)
(7, 8)

public static void main(String[] args) {

    // A: 第一种
    List<Integer> xList = Arrays.asList(1, 3, 5, 7);
    List<Integer> yList = Arrays.asList(2, 4, 6, 8, 10);

    List<int[]> collect = xList.stream().
            flatMap(
                    i -> yList.stream()
                            .map(j -> new int[]{i, j})
            )
            .collect(Collectors.toList());
    collect.stream()
            .forEach(a -> System.out.println("(" + a[0] + ", " + a[1] + ")"));


    // B:第二种
    int[] xArr = {1, 3, 5, 7};
    int[] yArr = {2, 4, 6, 8, 10};
    List<int[]> intsList = Arrays.stream(xArr)
            .flatMap(i -> Arrays.stream(yArr)
                    .map(j -> new int[]{i, j})
            )
            .collect(Collectors.toList());
    // 这块会报错: Bad return type in lambda expression: int[] cannot be converted to int
}
###

将IntStream转为Stream<Integer>就好了

int[] xArr = {1, 3, 5, 7};
int[] yArr = {2, 4, 6, 8, 10};
List<int[]> intsList = Arrays.stream(xArr).boxed()
    .flatMap(i -> Arrays.stream(yArr).boxed().map(j -> new int[]{i, j}))
    .collect(Collectors.toList());
###

修改方法其实之前echohw的回答已经写出来

至于为什么会报这个错,可以比对一下A中的map(j -> new int[]{i, j})B中的map(j -> new int[]{i, j})

看起来都是调用的map方法,但是实际上这是两个不同Streammap的方法

AStreammap方法
BIntStreammap方法

并且Streammap方法入参是一个Function
image.png

也就是提供一个引用类型参数返回另一个引用类型结果,这是引用类型的@FunctionalInterface
image.png

IntStreammap方法入参是一个IntUnaryOperator
image.png

它要求提供一个int参数,返回另一个int结果,相当于这是基本类型的@FunctionalInterface
image.png

ok,了解以上,我们再回过头看AB的处理过程就明白为啥A不报错,而B要报错了

AyList.stream().map(j -> new int[]{i, j})

  1. 此时stream()方法后,流里的元素是Integer,是引用类型
  2. map方法入参需要一个Function
  3. 现在lambda表达式:j -> new int[]{i, j},即Integer—>int[](数组也是引用类型哈),那这种形式满足Function所以不报错

B中的Arrays.stream(yArr).map(j -> new int[]{i, j})

  1. 此时stream()方法后,流里的元素是int,是基本类型
  2. map方法入参需要一个IntUnaryOperator
  3. 现在lambda表达式:j -> new int[]{i, j},即int—>int[],但是IntUnaryOperator返回需要一个int结果,因此编译器需要帮你做一个强转,但是恰好,int[]又不能强转成int,所以会报错

综上,因为你最终想要List<int[]>,所以ABstream的起点元素不同,那后续使用的方式就不同,因此才有echohw中写的,再做一次装箱操作boxed()把基本类型转换成引用类型

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • elementUI表单Object.assign处理后无法

    elementUI表单Object.assign处理后无法

  • nacos作为配置中,有时可以加载到配置

    nacos作为配置中,有时可以加载到配置

  • font-spider压缩字体后,文件大小没有

    font-spider压缩字体后,文件大小没有

  • Vue SSR babel node_modules中的一个包

    Vue SSR babel node_modules中的一个包

腾讯云代理商
海外云服务器