使用Java 8流计算两个int数组的笛卡尔积

5
我有两个int数组,a = {10,20,30}{1,2,3}
我想得到这两个数组的笛卡尔积
当我使用IntegerList时,逻辑可以正常工作:
    List<Integer> intList = Arrays.asList(10,20,30);
    List<Integer> intList1 = Arrays.asList(1,2,3);
    intList.stream().flatMap(i -> intList1.stream().map(j -> new int[]{i,j})).collect(Collectors.toList());

然而,当我使用int[]时,我遇到了编译错误。

错误:(16,79)java:不兼容的类型:lambda表达式中的错误返回类型 没有类型变量U的实例存在,以便java.util.stream.Stream符合java.util.stream.IntStream

    int[] intArray = {10,20,30};
    int[] intArray1 = {1,2,3};
    Arrays.stream(intArray).flatMap(i -> Arrays.stream(intArray1).mapToObj(j -> new int[]{j,i})).collect(Collectors.toList());

请帮助我理解这里有什么问题。

附言:

Arrays.stream(intArray).mapToObj(i -> new int[]{i,i+1}).collect(Collectors.toList());

产生的输出为 {(10,11),(20,21),(30,31)}
1个回答

10
在第二种情况下,Arrays.stream(intArray) 返回一个 IntStream
因此,flatMap() 期望参数是兼容的流类型:
Arrays.stream(intArray)
      .flatMap(i -> Arrays.stream(intArray1)
                     .mapToObj(j -> new int[] { j, i }))

但是 flatMap() 的 lambda 产生一个 Stream<int[]> ,你不能隐式地将 IntStream 映射到 Stream
这就是编译错误的原因。
所以,首先要将你的 IntStream 映射到 Stream<Integer>

List<int[]> collect = 
Arrays.stream(intArray)
      .boxed()
      .flatMap(i -> Arrays.stream(intArray1)
                          .mapToObj(j -> new int[] { j, i }))
      .collect(Collectors.toList());

由于整数装箱,它比您最初的意图效率低,但它能够工作。
请注意,通常情况下,您必须避免创建数组的列表。它们不是为良好协同工作而设计的。
这一般也适用于流。

编辑

Holger提供的解决方案作为评论可以避免装箱:

List<int[]> collect = Arrays.stream(intArray)
                                  .mapToObj(i -> Arrays.stream(intArray1)
                                                       .mapToObj(j -> new int[] { j, i }))
                                  .flatMap(Function.identity())
                                  .collect(Collectors.toList());

它首先将IntStream映射为Stream<Stream<int[]>>,然后调用flatMap()将其融合为<Stream<int[]>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接