其他流的笛卡尔积的流,每个元素作为List?

如何使用Java 8实现一个函数来获取一些流,并生成一个流,其中每个元素都是一个由流的笛卡尔积的一个成员组成的列表?

我看过这个问题 – 这个问题使用了一个BinaryOperator的聚合BinaryOperator (取两个类似的类型并生成相同类型的项目)。 我希望最终结果中的项目是List而不是输入流中元素的类型。

具体而言,假设我所需的function称为product ,如下:

 Stream<List> result = product( Stream.of("A", "B", "C", "D"), Stream.of("I", "J", "K), Stream.of("Y", "Z") ); result.forEach(System.out::println); 

应该打印:

 [A, I, Y] [A, I, Z] [A, J, Y] [A, J, Z] [A, K, Y] [A, K, Z] [B, I, Y] ... [D, K, Y] [D, K, Z] 

理想情况下,我希望这个操作尽可能地懒惰。 例如,如果输入流是由Stream.generate() ,那么如果这些流的供应商在绝对需要之前没有被执行,那就太好了。

可能的解决方案如下:

 private static  Stream> product(Stream... streams) { if (streams.length == 0) { return Stream.empty(); } List> cartesian = streams[streams.length - 1].map(x -> Collections.singletonList(x)).collect(Collectors.toList()); for (int i = streams.length - 2; i >= 0; i--) { final List> previous = cartesian; cartesian = streams[i].flatMap(x -> previous.stream().map(p -> { final List list = new ArrayList(p.size() + 1); list.add(x); list.addAll(p); return list; })).collect(Collectors.toList()); } return cartesian.stream(); } public static void main(String... args) { final Stream> result = product( Stream.of("A", "B", "C", "D"), Stream.of("I", "J", "K"), Stream.of("Y", "Z") ); result.forEach(System.out::println); } 

product-call返回一个Stream>结果,其打印为

 [A, I, Y] [A, I, Z] [A, J, Y] [A, J, Z] [A, K, Y] [A, K, Z] [B, I, Y] [B, I, Z] [B, J, Y] [B, J, Z] [B, K, Y] [B, K, Z] [C, I, Y] [C, I, Z] [C, J, Y] [C, J, Z] [C, K, Y] [C, K, Z] [D, I, Y] [D, I, Z] [D, J, Y] [D, J, Z] [D, K, Y] [D, K, Z]