0

Let's say I have a List<Object> with 100 objects into. What's the best way with Java 8 (without any tierce library) to get a List<List<Object>> wich contains 10 List of 10 Object ?

BnJ
  • 1,024
  • 6
  • 18
  • 37
  • 2
    @birryree can you read the post before replying please, it is mentionned Java8 – Moussi Dec 12 '17 at 15:32
  • @Moussi Just because it mentions Java 8 doesn't mean that non-Java8 specific answers don't apply. – wkl Dec 12 '17 at 15:35
  • @birryree with classic java you can do everything but the poster is searching for a java8 solution. – Moussi Dec 12 '17 at 15:39
  • Solution depends on how do you want to split that list. Do you want to *group* them by some common property? Or maybe based on their position in list? – Pshemo Dec 12 '17 at 15:39

4 Answers4

2

You need an external final counter but this seems to work.

    // Must be final (or implicitly final). 
    AtomicInteger n = new AtomicInteger();
    Map<String, List<Integer>> groups = IntStream.range(0, 100)
            .boxed()
            .collect(Collectors.groupingBy(
                    // Group by n / 10.
                    o -> String.valueOf(n.getAndIncrement() / 10)
                    )
            );
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
1

I'd first take the chuck size (10 elements, in your case), and then go over the list and use subList to take chunks out of it. E.g.:

List<List<Object>> subLists = IntStream
    .range(0, (int) Math.ceil((double) list.size() / subListSize))
    .mapToObj(i -> new ArrayList<>
                       (list.subList(i * subListSize, (i + 1) * subListSize)))
    .collect(Collectors.toList());

Note: The casting to double and ceiling is down in order to avoid integer division in case the subListSize doesn't divide list.size() exactly.

Mureinik
  • 297,002
  • 52
  • 306
  • 350
1

it's more simple using guava (you mentionned in you post without any tierce library i put this anyway)

@Test
public void givenList_whenParitioningIntoNSublists_thenCorrect() {
    List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
    List<List<Integer>> subSets = Lists.partition(intList, 3);

    List<Integer> lastPartition = subSets.get(2);
    List<Integer> expectedLastPartition = Lists.<Integer> newArrayList(7, 8);
    assertThat(subSets.size(), equalTo(3));
    assertThat(lastPartition, equalTo(expectedLastPartition));
}
Moussi
  • 470
  • 6
  • 16
1

In java 9 you can generate the indices with an IntStream using takeWhile and then using those indices take subLists from the original list. This should work for any List of Objects:

private static final int BATCH_SIZE = 10;

public void test(){
    List<List<Object>> batchedLists = split(generateTestObjects());
}

public List<List<Object>> split(List<Object> objects) {
    return IntStream.iterate(0, n -> n + BATCH_SIZE)
            .takeWhile(n -> n < objects.size())
            .map(t -> objects.subList(t, Math.min(t + BATCH_SIZE, objects.size()))
            .collect(Collectors.toList());
}

public List<Object> generateTestObjects(){
    return IntStream.range(0, 100)
            .boxed()
            .collect(Collectors.toList());
}
Vice Simunov
  • 101
  • 4