Here are three solutions, the first is for a list of lists. The second is for an array of arrays. Each method throws an exception if the supplied array length is not an integral multiple of the group size.
The third method permits non integral multiples of the group size.
All the methods utilize nested streams to create the desired result.
int[] v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
List<?> lists = groupLists(v, 4);
for (Object o : lists) {
System.out.println(o);
}
int[][] vals = groupArrays(v, 4);
for (int[] o : vals) {
System.out.println(Arrays.toString(o));
}
Both of the above print
[0, 4, 8]
[1, 5, 9]
[2, 6, 10]
[3, 7, 11]
Method to return lists
public static List<List<Integer>> groupLists(final int[] vals,
final int groupSize) {
if (vals.length % groupSize != 0) {
throw new IllegalArgumentException(
"Array length not a multiple of group size");
}
return IntStream.range(0, groupSize)
.mapToObj(i -> IntStream
.range(0, vals.length / groupSize)
.mapToObj(k -> Integer
.valueOf(vals[k * groupSize + i]))
.collect(Collectors.toList()))
.collect(Collectors.toList());
}
Method to return arrays
public static int[][]
groupArrays(final int[] vals, final int groupSize) {
if (vals.length % groupSize != 0) {
throw new IllegalArgumentException(
"Array length not a multiple of group size");
}
return IntStream.range(0, groupSize).mapToObj(
i -> IntStream.range(0, vals.length / groupSize).map(
k -> Integer.valueOf(vals[k * groupSize + i]))
.toArray())
.toArray(int[][]::new);
}
This method fills out the returned lists a much as possible by using a filter to avoid generating an index out of bounds exception.
int[] v = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
List<?> lists = groupListsPartial(v, 4);
for (Object o : lists) {
System.out.println(o);
}
prints
[0, 4, 8]
[1, 5, 9]
[2, 6]
[3, 7]
The method
public static List<List<Integer>> groupListsPartial(final int[] vals,
final int groupSize) {
return IntStream.range(0, groupSize)
.mapToObj(i -> IntStream
.range(0, (vals.length+(groupSize-1)) / groupSize)
.filter(k->k*groupSize + i <vals.length)
.mapToObj(k -> Integer
.valueOf(vals[k * groupSize + i]))
.collect(Collectors.toList()))
.collect(Collectors.toList());
}