How about a solution that wouldn't care if you changed the size of the ArrayList?
public static void main(String args[]) { ArrayList<Integer> ali = new ArrayList<>(); ali.add(1); ali.add(2); ali.add(3); System.out.println(combinations(ali).toString().replace("], [", "],\n [")); }
This is just a little help at the start.
public static List<List<Integer>> combinations(List<Integer> input) { return step(input, input.size(), new ArrayList<>()); }
This is the recursive method,
public static List<List<Integer>> step(List<Integer> input, int k, List<List<Integer>> result) { // We're done if (k == 0) { return result; } // Start with [[1], [2], [3]] in result if (result.size() == 0) { for (Integer i : input) { ArrayList<Integer> subList = new ArrayList<>(); subList.add(i); result.add(subList); } // Around we go again. return step(input, k - 1, result); } // Cross result with input. Taking us to 2 entries per sub list. Then 3. Then... List<List<Integer>> newResult = new ArrayList<>(); for (List<Integer> subList : result) { for(Integer i : input) { List<Integer> newSubList = new ArrayList<>(); newSubList.addAll(subList); newSubList.add(i); newResult.add(newSubList); } } // Around we go again. return step(input, k - 1, newResult); }
Outputs:
[[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 3, 1], [1, 3, 2], [1, 3, 3], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 3, 1], [2, 3, 2], [2, 3, 3], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 3, 1], [3, 3, 2], [3, 3, 3]]