java8-stream-flatMap

niewj
  • 305

下面的代码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
}
回复
阅读 1.4k
2 个回答
✓ 已被采纳

修改方法其实之前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()把基本类型转换成引用类型

echohw
  • 4
新手上路,请多包涵

将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());
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏