Eclipse Collections by Example: Collect
Learn how to transform a collection using the collect
method in Eclipse Collections.
What is Collect?
The method named collect
in Eclipse Collections takes a Function
as a parameter, applies that function to each element in a collection, and returns a the resulting collection. This method is the equivalent of the method named map
on the java.util.Stream
class in the JDK.
The method collect
in Eclipse Collections derives its name from the Smalltalk method named collect
. The method collect
will return the same collection type as the source collection (where feasible), but the value type contained in the collection may be different. The method collect
in Eclipse Collections should not be confused with the method collect
on java.util.Stream
which takes a Collector
. The method collect on Stream
is a more general mutable reduction which may return any type. The method collect
on java.util.Stream
does not appear onjava.util.Collection
or any of its extensions. So while there is a conceptual naming collision, there is no overloading of the methods to cause extra confusion.
Collecting from a List
@Test
public void collectingFromAListJava8()
{
ExecutorService executor = Executors.newWorkStealingPool();
MutableList<Integer> mList = mList(1, 2, 3, 4, 5);
ImmutableList<Integer> iList = iList(1, 2, 3, 4, 5);
Function<Integer, Integer> squared = i -> i * i;
MutableList<Integer> mutable = mList.collect(squared);
ImmutableList<Integer> immutable = iList.collect(squared);
LazyIterable<Integer> lazy = mList.asLazy().collect(squared);
ParallelListIterable<Integer> parallel =
mList.asParallel(executor, 2).collect(squared);
ImmutableList<Integer> expected = iList(1, 4, 9, 16, 25);
Assert.assertEquals(expected, mutable);
Assert.assertEquals(expected, immutable);
Assert.assertEquals(expected, lazy.toList());
Assert.assertEquals(expected, parallel.toList());
}
Collecting from a primitive List
@Test
public void collectingFromAPrimitiveListJava8()
{
MutableIntList mList = IntLists.mutable.with(1, 2, 3, 4, 5);
ImmutableIntList iList = IntLists.immutable.with(1, 2, 3, 4, 5);
IntToIntFunction squared = i -> i * i;
MutableIntList mutable =
mList.collectInt(squared, new IntArrayList());
ImmutableIntList immutable =
iList.collectInt(squared, new IntArrayList())
.toImmutable();
LazyIntIterable lazy =
mList.asLazy().collectInt(squared);
MutableIntList expected =
IntLists.mutable.with(1, 4, 9, 16, 25);
Assert.assertEquals(expected, mutable);
Assert.assertEquals(expected, immutable);
Assert.assertEquals(expected, lazy.toList());
}
Is it possible to collect selectively?
There is a method named collectIf
which applies a Predicate
first to each element, and then applies a Function
to each element where the Predicate
returned true
. This method is a fused form of select
and collect
. It is also possible to just call select
followed by collect
either eagerly, lazily or in parallel.
@Test
public void collectingSelectively()
{
var executor = Executors.newWorkStealingPool();
var mutableList = mList(1, 2, 3, 4, 5);
var immutableList = iList(1, 2, 3, 4, 5);
Function<Integer, Integer> squared = i -> i * i;
Predicate<Integer> evens = i -> i % 2 ==0;
var mutable = mutableList.collectIf(evens, squared);
var immutable = immutableList.collectIf(evens, squared);
var lazy1 =
mutableList.asLazy().collectIf(evens, squared);
var lazy2 =
mutableList.asLazy().select(evens).collect(squared);
var parallel1 =
mutableList.asParallel(executor, 2)
.collectIf(evens, squared);
var parallel2 =
mutableList.asParallel(executor, 2)
.select(evens).collect(squared);
var expected = iList(4, 16);
Assert.assertEquals(expected, mutable);
Assert.assertEquals(expected, immutable);
Assert.assertEquals(expected, lazy1.toList());
Assert.assertEquals(expected, lazy2.toList());
Assert.assertEquals(expected, parallel1.toList());
Assert.assertEquals(expected, parallel2.toList());
}
Notice that Function
and Predicate
cannot be replaced with var
. This is because a lambda must be assigned to some type.
APIs covered in the examples
Collect
(Eager, Lazy and Parallel) — transforms elements of a source collection to a new collectionCollectIf
(Eager, Lazy and Parallel) — transforms the elements of a source collection which satisfy a given predicate to a new collectionmList
— Creates aMutableList
iList
— Creates anImmutableList
IntLists.mutable.with
— Creates aMutableIntList
IntLists.immutable.with
— Creates anImmutableIntList
asLazy
— Returns aLazyIterable
orLazyIntIterable
asParallel
— Returns aParallelIterable
toList
— Converts the targetIterable
into aMutableList
var
— Local variable Type Inference included in Java 10 (JEP 286)
Check out this presentation to learn more about the origins, design and evolution of the Eclipse Collections API. There is also a video covering the slides that was recorded at an Eclipse Community Virtual Meet-up.
Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.