Cartesian product flow of other flows, each element as a List?

How can I implement a function using Java 8 to accept a certain number of threads and create a thread in which each element is a list consisting of one member of the Cartesian product of the threads?

I examined this question - this question uses an aggregator, which is a BinaryOperator (taking two elements of a similar type and creating an element of the same type). I would like the elements in the end result to be List , not the types of elements in the input streams.

Specifically, assuming my desired function is called product , the following:

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

should print:

 [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] 

Ideally, I would like this operation to be as lazy as possible. For example, if input streams are created using Stream.generate() , it would be great if the providers of these streams were not executed until they were absolutely necessary.

+7
source share
1 answer

A possible solution is as follows:

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

The call product returns the result Stream<List<String>> , which prints as

 [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] 
+1
source

All Articles