The map-and-reduce approach using nested loops
Prepare a list of lists List<List<T>>
populated with a single empty value. This list is used further as a storage of intermediate results and as a final result.
Sequentially append the data from incoming lists List<List<T>>
to the intermediate result and obtain the final result. Schematically, this iterative process looks as follows:
result0: [[]]
list1: [1,2]
-------
result1: [[1],[2]]
list2: [3,4]
-------
result2: [[1,3],[1,4],[2,3],[2,4]]
list3: [5,6]
-------
result3: [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
Try it online!
/**
* @param lists an arbitrary number of lists
* @param <T> the type of the elements
* @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();
// Cartesian product, intermediate result
List<List<T>> cp = Collections.singletonList(Collections.emptyList());
// iterate through incoming lists
for (List<T> list : lists) {
// non-null and non-empty lists
if (list == null || list.size() == 0) continue;
// intermediate result for next iteration
List<List<T>> next = new ArrayList<>();
// rows of current intermediate result
for (List<T> row : cp) {
// elements of current list
for (T el : list) {
// new row for next intermediate result
List<T> nRow = new ArrayList<>(row);
nRow.add(el);
next.add(nRow);
}
}
// pass to next iteration
cp = next;
}
// Cartesian product, final result
return cp;
}
public static void main(String[] args) {
List<List<Integer>> lists = prepareLists(3);
List<List<Integer>> cp = cartesianProduct(lists);
// output without spaces
System.out.println(lists.toString().replace(" ", ""));
System.out.println(cp.toString().replace(" ", ""));
}
// supplementary method, prepares lists for multiplication
public static List<List<Integer>> prepareLists(int n) {
List<List<Integer>> lists = new ArrayList<>(n);
for (int i = 1; i <= n; i++)
lists.add(Arrays.asList(i * 2 - 1, i * 2));
return lists;
}
Output:
[[1,2],[3,4],[5,6]]
[[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]
See also: Generate all combinations from multiple lists