Split / Partition a list

This example will demonstrate how to partition an ArrayList using java, java 8, guava and apache commons. The setup data is a List of strings that will be broken up into consecutive sublists of the condition specified.

Setup

List<String> playerDecisions = Lists.newArrayList(
            "Hit",
            "Stand",
            "Double down",
            "Split",
            "Surrender");

Straight up Java

This snippet will use a for loop to break apart a list of strings into a sublist.

@Test
public void partition_list_java () {

    List<List<String>> decisionsBy2 = new ArrayList<List<String>>();

    final int sizeOfList = playerDecisions.size();
    final int breakApart = 2;

    for (int i = 0; i < sizeOfList; i += breakApart) {
        decisionsBy2.add(new ArrayList<String> (
            playerDecisions.subList(i, Math.min(sizeOfList, i + breakApart)))
        );
    }

    logger.info(decisionsBy2);

    assertThat(decisionsBy2.get(0), hasItems("Hit", "Stand"));
    assertThat(decisionsBy2.get(1), hasItems("Double down", "Split"));
    assertThat(decisionsBy2.get(2), hasItems("Surrender"));
}

Output

[
    [Hit, Stand],
    [Double down, Split],
    [Surrender]
]

Java 8

Using java 8, the snippet will show how to use a partitioning function. The partitioning function will return Map < Boolean,List < String >> where the key is a boolean and the results are based on the behavior of the predicate. Created by a lambda expression, the predicate shown will return true if the string starts with 's'. The resulting map will have a collection of strings that start with 's' where the key equals true and false where a list of strings do not start with 's'. So at most you will have two keys or two different groups. This return collection type is similiar to guava multimap.

@Test
public void partition_list_java8() {

    Predicate<String> startWithS = p -> p.toLowerCase().startsWith("s");

    Map<Boolean, List<String>> decisionsByS = playerDecisions.stream()
            .collect(Collectors.partitioningBy(startWithS));

    logger.info(decisionsByS);

    assertTrue(decisionsByS.get(Boolean.TRUE).size() == 3);
}

Output

{false=[Hit, Double down], true=[Stand, Split, Surrender]}

Google Guava

This snippet will show how to split an ArrayList into smaller arraylists using guava. Guava's Lists collection utiltiy partition method will return a sublist of a list, with each sublist the same size and the last varying in size depending on the number of elements.

@Test
public void partition_list_guava () {

    List<List<String>> decisionsBy2 = Lists.partition(playerDecisions, 2);

    logger.info(decisionsBy2);

    assertThat(decisionsBy2.get(0), hasItems("Hit", "Stand"));
    assertThat(decisionsBy2.get(1), hasItems("Double down", "Split"));
    assertThat(decisionsBy2.get(2), hasItems("Surrender"));
}

Output

[
    [Hit, Stand],
    [Double down, Split],
    [Surrender]
]

Apache Commons

This snippet will show how to divide a list into multiple lists with apache commons.

@Ignore("Will be released in collections 4")
@Test
public void partition_list_apache_commons () {
    // TODO not yet released, collections 4
    // ListUtils.partition(playerDecisions, 2)
    // http://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/ListUtils.html#partition(java.util.List, int)
}