Home Tutorials Training Consulting Products Books Company Donate Contact us









Online Training

Quick links

Share

Partition a collection into smaller collections. This article describes how to partition a collections into a given number of smaller collections.
-->

2. Partition collection in Java

2.1. Implementation

Create a Java project "de.vogella.algorithms.partitioncollection".

Create the following program.

package de.vogella.algorithms.partitioncollection;

import java.util.AbstractList;
import java.util.List;


public class MyPartition {

     /**
       * Returns consecutive {@linkplain List#subList(int, int) sublists} of a list,
       * each of the same size (the final list may be smaller). For example,
       * partitioning a list containing {@code [a, b, c, d, e]} with a partition
       * size of 3 yields {@code [[a, b, c], [d, e]]} -- an outer list containing
       * two inner lists of three and two elements, all in the original order.
       *
       * <p>The outer list is unmodifiable, but reflects the latest state of the
       * source list. The inner lists are sublist views of the original list,
       * produced on demand using {@link List#subList(int, int)}, and are subject
       * to all the usual caveats about modification as explained in that API.
       *
       * * Adapted from http://code.google.com/p/google-collections/
       *
       * @param list the list to return consecutive sublists of
       * @param size the desired size of each sublist (the last may be
       *     smaller)
       * @return a list of consecutive sublists
       * @throws IllegalArgumentException if {@code partitionSize} is nonpositive
       *

       */


      public static <T> List<List<T>> partition(List<T> list, int size) {

       if (list == null)
          throw new NullPointerException(
              "'list' must not be null");
        if (!(size > 0))
          throw new IllegalArgumentException(
              "'size' must be greater than 0");

        return new Partition<T>(list, size);
      }

      private static class Partition<T> extends AbstractList<List<T>> {

        final List<T> list;
        final int size;

        Partition(List<T> list, int size) {
          this.list = list;
          this.size = size;
        }

        @Override
        public List<T> get(int index) {
          int listSize = size();
          if (listSize < 0)
            throw new IllegalArgumentException("negative size: " + listSize);
          if (index < 0)
            throw new IndexOutOfBoundsException(
                "index " + index + " must not be negative");
          if (index >= listSize)
            throw new IndexOutOfBoundsException(
                "index " + index + " must be less than size " + listSize);
          int start = index * size;
          int end = Math.min(start + size, list.size());
          return list.subList(start, end);
        }

        @Override
        public int size() {
          return (list.size() + size - 1) / size;
        }

        @Override
        public boolean isEmpty() {
          return list.isEmpty();
        }
      }


}

2.2. Test

You can use the following JUnit test to validate the result.

package de.vogella.algorithms.partitioncollection;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import static org.junit.Assert.assertTrue;


public class MyPartitionTest {
    @Test
    public void partitiontest1() {
        List<String> list = new ArrayList<String>();
        list.add("one");
        list.add("two");
        list.add("three");
        list.add("four");
        list.add("five");
        list.add("six");
        list.add("seven");
        list.add("eight");
        list.add("nine");
        list.add("ten");
        list.add("eleven");
        List<List<String>> partition = MyPartition.partition(list, 1);
        System.out.println(partition.get(2).size());
        assertTrue(partition.size()==11);
        assertTrue(partition.get(0).size()==1);
        partition = MyPartition.partition(list, 7);
        assertTrue(partition.size()==2);
        assertTrue(partition.get(0).size()==7);
        assertTrue(partition.get(1).size()==4);

        // now let assume you want to have x number of buckets
        // How many elements must placed in a list?
        // Take x as 3

        int buckets = 3;
        int divide = list.size() / buckets;
        if (list.size() % buckets !=0){
            divide ++;
        }
        System.out.println("Max. number of element in each bucket " + divide);
        partition = MyPartition.partition(list, divide );
        assertTrue(partition.size()==buckets);
    }
}
-->

Copyright © 2012-2018 vogella GmbH. Free use of the software examples is granted under the terms of the Eclipse Public License 2.0. This tutorial is published under the Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Germany license.

See Licence.