Eclipse Collections by Example: Filtering

Donald Raab
4 min readMar 15, 2018

--

Learn how to filter a collection using Eclipse Collections.

Photo by Tyler Nix on Unsplash

Filtering: Include or Exclude?

If you have a single method named filter, how do you know if it is supposed to be an inclusive or exclusive filter? In Eclipse Collections, there are two filtering methods named select and reject.

The method select is an inclusive filter. Select will include all elements that return true when evaluated against a specified Predicate. The method reject is an exclusive filter. Reject will exclude all elements that return true when evaluated against a specified Predicate.

The above visualization demonstrates the results of calling select and reject given a list of integral values from one to five. The Predicate here will evaluate to true for elements that are even. The methods select and reject will determine whether an element matching the Predicate is included or excluded.

Filtering an Object List

The following examples show how to use select and reject on a List of Integer values. A MutableList<Integer> and ImmutableList<Integer> are both included here to demonstrate that the select and reject methods are defined with covariant return types. A MutableList<Integer> will return a MutableList<Integer> for both select and reject. Likewise, an ImmutableList<Integer> will return an ImmutableList<Integer> for both select and reject. I demonstrate using serial/eager versions of select and reject, as well as serial/lazy and parallel/lazy versions.

@Test
public void filteringUsingSelectAndReject()
{
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;

// Serial Eager Inclusive Filter with Covariant Return Type
MutableList<Integer> evensMutable = mList.select(evens);

// Serial Eager Inclusive Filter with Covariant Return Type
ImmutableList<Integer> evensImmutable = iList.select(evens);

// Serial Lazy Inclusive Filter
LazyIterable<Integer> evensLazy = mList.asLazy().select(evens);

ExecutorService executor = Executors.newWorkStealingPool();

// Parallel Lazy Inclusive Filter
ParallelListIterable<Integer> evensParallel =
mList.asParallel(executor, 2).select(evens);

ImmutableList<Integer> expectedEvens = iList(2, 4);
Assert.assertEquals(expectedEvens, evensMutable);
Assert.assertEquals(expectedEvens, evensImmutable);
// Convert LazyIterable to List for equals comparison
Assert.assertEquals(expectedEvens, evensLazy.toList());
// Convert Lazy ParallelListIterable to List for equals comparison
Assert.assertEquals(expectedEvens, evensParallel.toList());

// Serial Eager Exclusive Filter with Covariant Return Type
MutableList<Integer> oddsMutable = mList.reject(evens);

// Serial Eager Exclusive Filter with Covariant Return Type
ImmutableList<Integer> oddsImmutable = iList.reject(evens);

// Serial Lazy Exclusive Filter
LazyIterable<Integer> oddsLazy = mList.asLazy().reject(evens);

// Parallel Lazy Exclusive Filter
ParallelListIterable<Integer> oddsParallel =
mList.asParallel(executor, 2).reject(evens);

ImmutableList<Integer> expectedOdds = iList(1, 3, 5);
Assert.assertEquals(expectedOdds, oddsMutable);
Assert.assertEquals(expectedOdds, oddsImmutable);
Assert.assertEquals(expectedOdds, oddsLazy.toList());
Assert.assertEquals(expectedOdds, oddsParallel.toList());
}

Filtering a primitive List

The following examples show how to use select and reject on a primitive List of int values. A MutableIntList and ImmutableIntList are both included here to demonstrate that the select and reject methods are defined with covariant return types. A MutableIntList will return a MutableIntList for both select and reject. Likewise, an ImmutableIntList will return an ImmutableIntList for both select and reject. I demonstrate using serial/eager versions of select and reject, as well as serial/lazy versions.

@Test
public void filteringPrimitivesUsingSelectAndReject()
{
MutableIntList mList = IntLists.mutable.with(1, 2, 3, 4, 5);
ImmutableIntList iList = IntLists.immutable.with(1, 2, 3, 4, 5);
IntPredicate evens = i -> i % 2 == 0;

// Serial Eager Inclusive Filter with Covariant Return Type
MutableIntList evensMutable = mList.select(evens);

// Serial Eager Inclusive Filter with Covariant Return Type
ImmutableIntList evensImmutable = iList.select(evens);

// Serial Lazy Inclusive Filter
LazyIntIterable evensLazy = mList.asLazy().select(evens);

MutableIntList expectedEvens = IntLists.mutable.with(2, 4);
Assert.assertEquals(expectedEvens, evensMutable);
Assert.assertEquals(expectedEvens, evensImmutable);
// Convert LazyIntIterable to List for equals comparison
Assert.assertEquals(expectedEvens, evensLazy.toList());

// Serial Eager Exclusive Filter with Covariant Return Type
MutableIntList oddsMutable = mList.reject(evens);

// Serial Eager Exclusive Filter with Covariant Return Type
ImmutableIntList oddsImmutable = iList.reject(evens);

// Serial Lazy Exclusive Filter
LazyIntIterable oddsLazy = mList.asLazy().reject(evens);

MutableIntList expectedOdds = IntLists.mutable.with(1, 3, 5);
Assert.assertEquals(expectedOdds, oddsMutable);
Assert.assertEquals(expectedOdds, oddsImmutable);
Assert.assertEquals(expectedOdds, oddsLazy.toList());
}

What other types support Select and Reject?

The Symmetric Sympathy is strong with select and reject. The mindmaps below show the specialization of select and reject methods that return covariant return types.

Select and Reject is available across many types and concerns

Possible to filter both inclusively and exclusively in one iteration?

Yes. There is a method called partition. I will show partition in the next blog in this series.

APIs covered in the examples

  1. Select (Eager, Lazy and Parallel) — filters including elements that match a condition
  2. Reject (Eager, Lazy and Parallel) — filters excluding elements that match a condition
  3. mList — Creates a MutableList
  4. iList — Creates an ImmutableList
  5. IntLists.mutable.with — Creates a MutableIntList
  6. IntLists.immutable.with — Creates an ImmutableIntList
  7. asLazy — Returns a LazyIterable or LazyIntIterable
  8. asParallel — Returns a ParallelIterable
  9. toList — Converts the target Iterable into a MutableList

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

--

--

Donald Raab
Donald Raab

Written by Donald Raab

Java Champion. Creator of the Eclipse Collections OSS Java library (https://github.com/eclipse/eclipse-collections). Inspired by Smalltalk. Opinions are my own.

No responses yet