Hidden Treasures of Eclipse Collections - Part 1
There are some hidden gems in the Eclipse Collections framework.
Join the DZone community and get the full member experience.
Join For FreeEclipse Collections is an open-source Java Collections framework. Please refer to the resources at the end of the blog for more information about the framework. In this blog, I am going to demonstrate five lesser-known features of the framework.
distinct()
: When you want to get unique items in yourList,
the typical way to get them is to add yourList
to aSet
. However, you lose the original order and end up with an unpredictable order of a hash table. Sometimes, you need to preserve the order in which we have visited the unique elements. We developeddistinct()
for this use case. When you calldistinct()
on an Eclipse CollectionsMutableList
, the result is aList
of unique elements.@Test public void distinct() { MutableList<Integer> integers = Lists.mutable.with( 1, 2, 2, 3, 3, 3, 4, 4, 4, 4); Assert.assertEquals( Lists.mutable.with(1, 2, 3, 4), integers.distinct()); }
If you cannot convert your originalList
into an Eclipse Collections List, you can useListAdapter
orListIterate
to get the same API.@Test public void distinctNonEclipseCollectionsList() { List<Integer> integersLinkedList = new LinkedList<>(integers); Assert.assertEquals( Lists.mutable.with(1, 2, 3, 4), ListAdapter.adapt(integersLinkedList).distinct()); Assert.assertEquals( Lists.mutable.with(1, 2, 3, 4), ListIterate.distinct(integersLinkedList)); }
If you needdistinct()
to be available for lazy evaluation, it is available on ourLazyIterable
as well.@Test public void distinctAsLazy() { MutableList<String> distinctStrings = integers.asLazy() .distinct() .collect(String::valueOf) .toList(); Assert.assertEquals( Lists.mutable.with("1", "2", "3", "4"), distinctStrings); }
selectInstancesOf()
: If you want to filter and return only the instances of a particular class, you can useselectInstancesOf()
.@Test public void selectInstancesOf() { MutableList<Number> numbers = Lists.mutable.with( 1.0, 2, 3.0, 4.0, 5); MutableList<Integer> integers = numbers .selectInstancesOf(Integer.class); Assert.assertEquals(Lists.mutable.with(2, 5), integers); }
If you cannot use an Eclipse Collections interface, you can always wrap your collections with our adapters or use our static utilityIterate
to get the same API.@Test public void selectInstancesOf() { List<Number> numberList = new ArrayList<>(numbers); MutableList<Integer> integersUsingAdapter = ListAdapter .adapt(numberList) .selectInstancesOf(Integer.class); Assert.assertEquals( Lists.mutable.with(2, 5), integersUsingAdapter); Collection<Integer> integersUsingIterate = Iterate .selectInstancesOf(numberList, Integer.class); Assert.assertEquals( Lists.mutable.with(2, 5), integersUsingIterate); }
chunk()
: If you want to divide your iterable into multiple iterables of a particular size, you can usechunk()
.@Test public void chunk() { MutableList<Integer> integers = Lists.mutable.with( 1, 2, 3, 4, 5); MutableList<MutableList<Integer>> expectedChunked = Lists.mutable.with( Lists.mutable.with(1, 2), Lists.mutable.with(3, 4), Lists.mutable.with(5)); Assert.assertEquals( expectedChunked, integers.chunk(2)); }
If you cannot use an Eclipse Collections interface, you can always wrap your collections with our adapters or use our static utilityIterate
to get the same API.@Test public void chunk() { List<Integer> integerList = new ArrayList<>(integers); RichIterable<RichIterable<Integer>> chunkUsingAdapter = ListAdapter .adapt(integerList) .chunk(2); Assert.assertEquals( expectedChunked, chunkUsingAdapter); RichIterable<RichIterable<Integer>> chunkUsingIterate = Iterate .chunk(integerList, 2); Assert.assertEquals( expectedChunked, chunkUsingIterate); }
as
vs.to
naming convention: In Eclipse Collections, we try to follow common conventions like the ones described in this blog. In Eclipse Collections, methods that start with the word “as” always take constant time and create constant garbage. Usually, that means returning a wrapper object. Some examples:asUnmodifiable()
– returns collection wrappers that throw on mutating methodsasSynchronized()
– returns collection wrappers that grab a lock before delegatingasLazy()
– returns a wrapper that supports lazy evaluation, by deferring evaluation of non-terminating operations and only evaluating when a terminating operation is encounteredasReversed()
– returns a lazy wrapper around a list that iterates in reverse order when computation is forcedasParallel()
(Beta) – returns a lazy wrapper that supports parallel execution
In Eclipse Collections, methods that start with the word “to” can take more time and create more garbage. Most of the time, that means creating a new collection in linear time. In the case of sorted collections, that grows toO(n log n)
. Some examples:toList()
– always creates a new copy, even when called on liststoSet()
,toBag()
,toStack()
,toMap()
,toArray()
– O(n) in time and memorytoSortedList()
,toSortedListBy()
,toSortedSet()
,toSortedSetBy()
,toSortedMap()
– O(n log n) timetoImmutable()
– O(n) time on mutable collectionstoReversed()
– same asasReversed()
but will have eager evaluationtoString()
– yes, it counts!
Summary
In this blog, I explained a few lesser-known features of Eclipse Collections : distinct()
, partition()
, selectInstancesOf()
,chunk()
, and as()
vs. to()
method naming conventions.
I hope you found this post informative. If you have not used Eclipse Collections before, give it a try. There are few resources below. Make sure you show us your support and put a star on our GitHub Repository
Eclipse Collections Resources
Eclipse Collections comes with its own implementations of List, Set, and Map. It also has additional data structures like Multimap, Bag, and an entire Primitive Collections hierarchy. Each of our collections has a rich API for commonly required iteration patterns.
Published at DZone with permission of Nikhil Nanivadekar. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments