Cartesian product of multiple lists
You can use the reduce
method with three parameters:
identity
- specify the result stub.
List<List<T>>
accumulator
- append elements of lists to the result.
List<List<T>> result, List<T> list
combiner
- is used in parallel mode, combines the results.
List<List<T>> result1, List<List<T>> result2
Try it online!
/**
* @param lists the lists for multiplication
* @param <T> the type of list element
* @return the Cartesian product
*/
public static <T> List<List<T>> cartesianProduct(List<List<T>> lists) {
// check if incoming data is not null
if (lists == null) return Collections.emptyList();
return lists.stream()
// non-null and non-empty lists
.filter(list -> list != null && list.size() > 0)
// stream of lists into a single list
.reduce(// identity - specify the result stub
Collections.singletonList(Collections.emptyList()),
// accumulator - append elements of lists to the result
(result, list) -> result.stream()
.flatMap(inner -> list.stream()
.map(el -> {
List<T> nList = new ArrayList<>(inner);
nList.add(el);
return nList;
}))
// list of combinations
.collect(Collectors.toList()),
// combiner - is used in parallel mode, combines the results
(result1, result2) -> {
result1.addAll(result2);
return result1;
});
}
public static void main(String[] args) {
List<String> l1 = Arrays.asList("A", "B");
List<String> l2 = Arrays.asList("C", "D");
List<String> l3 = Arrays.asList("E", "F");
List<List<String>> cp = cartesianProduct(Arrays.asList(l1, l2, l3));
// output
System.out.println(cp);
}
Output:
[[A,C,E],[A,C,F],[A,D,E],[A,D,F],[B,C,E],[B,C,F],[B,D,E],[B,D,F]]
See also: Cartesian product of 3 collections