Search code examples
javajava-8partitioning

Java 8 partition list


Is it possible to partition a List in pure Jdk8 into equal chunks (sublists).

I know it is possible using Guava Lists class, but can we do it with pure Jdk? I don't want to add new jars to my project, just for one use case.

SOLUTONS:

The best solution till now was presented by tagir-valeev:

I have also found three other possibilities, but they are ment for only few cases:

1.Collectors.partitioningBy() to split the list into 2 sublists – as follows:

intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());

2.Collectors.groupingBy() to split our list to multiple partitions:

 Map<Integer, List<Integer>> groups = 
      intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());

3.Split by separator:

List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8);

    int[] indexes = 
      Stream.of(IntStream.of(-1), IntStream.range(0, intList.size())
      .filter(i -> intList.get(i) == 0), IntStream.of(intList.size()))
      .flatMapToInt(s -> s).toArray();
    List<List<Integer>> subSets = 
      IntStream.range(0, indexes.length - 1)
               .mapToObj(i -> intList.subList(indexes[i] + 1, indexes[i + 1]))
               .collect(Collectors.toList());

4.Using Streams + counter source:

final List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7);
final int chunkSize = 3;
final AtomicInteger counter = new AtomicInteger();

final Collection<List<Integer>> result = numbers.stream()
    .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize))
    .values();

Solution

  • That can be done easily using the subList() method:

    List<String> collection = new ArrayList<>(21);
    // fill collection
    int chunkSize = 10;
    List<List<String>> lists = new ArrayList<>();
    for (int i = 0; i < collection.size(); i += chunkSize) {
        int end = Math.min(collection.size(), i + chunkSize);
        lists.add(collection.subList(i, end));
    }