EC by Example: Partitioning

Learn how to partition a collection using Eclipse Collections.

What is partitioning?

Partitioning is a kind of filtering, except that all elements of a collection are retained. Instead of being included (like select) or excluded (like jeject), the elements of the collection are split into two collections based on whether they return true or false when passed to a Predicate.

Image for post
Image for post
A partition contains both selected and rejected elements

Partitioning a List (Java 8)

@Test
public void partitioningLists()
{
MutableList<Integer> mList = mList(1, 2, 3, 4, 5);
ImmutableList<Integer> iList = iList(1, 2, 3, 4, 5);

Predicate<Integer> evens = i -> i % 2 == 0;

PartitionMutableList<Integer> mutable =
mList.partition(evens);

PartitionImmutableList<Integer> immutable =
iList.partition(evens);

PartitionIterable<Integer> lazy =
mList.asLazy().partition(evens);

ImmutableList<Integer> expectedEvens = iList(2, 4);
Assert.assertEquals(expectedEvens, mutable.getSelected());
Assert.assertEquals(expectedEvens, immutable.getSelected());
Assert.assertEquals(expectedEvens, lazy.getSelected().toList());

ImmutableList<Integer> expectedOdds = iList(1, 3, 5);
Assert.assertEquals(expectedOdds, mutable.getRejected());
Assert.assertEquals(expectedOdds, immutable.getRejected());
Assert.assertEquals(expectedOdds, lazy.getRejected().toList());
}

Partitioning a List (Java 10)

Here I will take advantage of local variable type inference using the var keyword in Java 10. With a type like PartitionMutableList, using var can significantly reduce the amount of noise in the code.

@Test
public void partitioningListsJava10()
{
var mutableList = mList(1, 2, 3, 4, 5);
var immutableList = iList(1, 2, 3, 4, 5);

Predicate<Integer> evens = i -> i % 2 == 0;

var mutable = mutableList.partition(evens);

var immutable = immutableList.partition(evens);

var lazy = mutableList.asLazy().partition(evens);

var expectedEvens = iList(2, 4);
Assert.assertEquals(expectedEvens, mutable.getSelected());
Assert.assertEquals(expectedEvens, immutable.getSelected());
Assert.assertEquals(expectedEvens, lazy.getSelected().toList());

var expectedOdds = iList(1, 3, 5);
Assert.assertEquals(expectedOdds, mutable.getRejected());
Assert.assertEquals(expectedOdds, immutable.getRejected());
Assert.assertEquals(expectedOdds, lazy.getRejected().toList());
}

Covariance at play

The return type for partition is determined by the source type. In the case of a MutableList as seen above, the method partition will return a PartitionMutableList. The following is a partial hierarchy of types that exist for partitioning a List. The full hierarchy includes similar relationships for Bag, Set, SortedSet, SortedBag and Stack.

A partial partition hierarchy for Lists

Partitioning a Set (Java 8)

@Test
public void partitioningSets()
{
MutableSet<Integer> mSet = mSet(1, 2, 3, 4, 5);
ImmutableSet<Integer> iSet = iSet(1, 2, 3, 4, 5);

Predicate<Integer> evens = i -> i % 2 == 0;

PartitionMutableSet<Integer> mutable =
mSet.partition(evens);

PartitionImmutableSet<Integer> immutable =
iSet.partition(evens);

PartitionIterable<Integer> lazy =
mSet.asLazy().partition(evens);

ImmutableSet<Integer> expectedEvens = iSet(2, 4);
Assert.assertEquals(expectedEvens, mutable.getSelected());
Assert.assertEquals(expectedEvens, immutable.getSelected());
Assert.assertEquals(expectedEvens, lazy.getSelected().toSet());

ImmutableSet<Integer> expectedOdds = iSet(1, 3, 5);
Assert.assertEquals(expectedOdds, mutable.getRejected());
Assert.assertEquals(expectedOdds, immutable.getRejected());
Assert.assertEquals(expectedOdds, lazy.getRejected().toSet());
}

Partitioning a Set (Java 10)

@Test
public void partitioningSetsJava10()
{
var mutableSet = mSet(1, 2, 3, 4, 5);
var immutableSet = iSet(1, 2, 3, 4, 5);

Predicate<Integer> evens = i -> i % 2 == 0;

var mutable = mutableSet.partition(evens);

var immutable = immutableSet.partition(evens);

var lazy = mutableSet.asLazy().partition(evens);

var expectedEvens = iSet(2, 4);
Assert.assertEquals(expectedEvens, mutable.getSelected());
Assert.assertEquals(expectedEvens, immutable.getSelected());
Assert.assertEquals(expectedEvens, lazy.getSelected().toSet());

var expectedOdds = iSet(1, 3, 5);
Assert.assertEquals(expectedOdds, mutable.getRejected());
Assert.assertEquals(expectedOdds, immutable.getRejected());
Assert.assertEquals(expectedOdds, lazy.getRejected().toSet());
}

APIs and features covered in the examples

  1. Partition (Eager and Lazy) — filters selecting and rejecting elements that based on a given condition. Partition is a terminal operation on LazyIterable, which forces execution to happen.
  2. mList — Creates a MutableList
  3. iList — Creates an ImmutableList
  4. mSet — Creates a MutableSet
  5. iSet — Creates an ImmutableSet
  6. asLazy — Returns a LazyIterable or LazyIntIterable
  7. toList — Converts the target Iterable into a MutableList
  8. toSet — Converts the target Iterable into a MutableSet
  9. var — Local variable Type Inference included in Java 10 (JEP 286)

Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.

Written by

Java Champion. Creator of the Eclipse Collections OSS Java library (http://www.eclipse.org/collections/). Inspired by Smalltalk. Opinions are my own.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store