Nine Features in Eclipse Collections 9.0

CountBy, DistinctBy, Cartesian Product for primitive collections… and more.

Image for post
Image for post

In my previous blog post, I described the upcoming release of Eclipse Collections 9.0.

In this post, I will briefly highlight nine features with examples that will be included in the Eclipse Collections 9.0 release. Each example shows what you could do in Eclipse Collections 7.x — 8.x and how it was improved in Eclipse Collections 9.0.

1. CountBy

// Eclipse Collections 7.x - 8.x
MutableBag<String> countsOld =
this.company.getCustomers()
.asLazy().collect(Customer::getCity).toBag();

It should be easier for developers to both discover and read countBy versus the previous alternative.

2. DistinctBy

// Eclipse Collections 7.x - 8.x
MutableList<Customer> distinctOld =
this.company.getCustomers()
.distinct(
HashingStrategies.fromFunction(Customer::getCity));

DistinctBy uses distinct with a HashingStrategy for its implementation.

3. Primitive Collection Factories work with Primitive Java Streams

// Eclipse Collections 7.x - 8.x
MutableIntList listOld =
IntStream.rangeClosed(1, 100)
.collect(
IntLists.mutable::empty,
MutableIntList::add,
MutableIntList::withAll);

There are also immutable factories that take IntStream, LongStream and DoubleStream. Both mutable and immutable factories that accept primitive Java Streams are available across primitive Lists, Sets, Bags, and Stacks for int, long and double. Symmetric Sympathy strikes again.

4. Factory classes can now create adapters

// Eclipse Collections 7.x - 8.x
MutableList<Object> listAdapter =
ListAdapter.adapt(new ArrayList<>());
MutableSet<Object> setAdapter =
SetAdapter.adapt(new ConcurrentSkipListSet<>());
MutableMap<Object, Object> mapAdapter =
MapAdapter.adapt(new LinkedHashMap<>());

Many developers do not realize there are adapter classes for existing JDK types in Eclipse Collections. Adding this short-cut on the factory classes should make it easier to discover.

5. Streams available directly on Immutable Collections

// Eclipse Collections 7.x - 8.x
boolean result =
Lists.immutable.with(1, 2, 3)
.castToList()
.stream()
.anyMatch(i -> i % 2 == 0);

This was a requested feature. It is not obvious that you can call castToList and then call stream on an ImmutableCollection. In this previous post I described the design decision to not have ImmutableCollection extend Collection. This is why it was necessary to add stream explicitly.

6. FlatCollect on primitive lazy iterables

// Eclipse Collections 8.x
IntList listOne = IntLists.mutable.with(1, 2, 3);
IntList listTwo = IntLists.mutable.with(4, 5, 6);
MutableList<IntIntPair> pairs = listOne
.flatCollect(i ->
listTwo.collect(j ->
PrimitiveTuples.pair(i, j)),
Lists.mutable.empty());

Previously, you could only flatCollect directly into a mutable primitive container. This method was an important building block for primitive cartesian product so it could be implemented lazily.

7. Streams available for values on all Object Valued Maps

// Eclipse Collections 7.x - 8.x - Object Maps
boolean result =
Maps.mutable.with(1, 1, 2, 2, 3, 3)
.values()
.stream()
.anyMatch(i -> i % 2 == 0);

All object valued maps implement RichIterable<V>. This was a conscious design decision made in the early days of Eclipse Collections. Unfortunately, the stream method is defined on Collection which Maps in Eclipse Collections do not extend. So the stream method had to be added explicitly.

8. AverageIfEmpty and MedianIfEmpty on primitive iterables

// Eclipse Collections 7.x - 8.x
double average = IntLists.mutable.empty().average();
// throws java.lang.ArithmeticException
double median = IntLists.mutable.empty().median();
// throws java.lang.ArithmeticException

Eclipse Collections had minIfEmpty and maxIfEmpty on primitive iterables but did not have the equivalent for average and median, which both throw on empty.

9. Primitive Sets now have Cartesian Product

// Eclipse Collections 7.x - 8.x
Set<Integer> a = Sets.mutable.with(1, 2, 3);
Set<Integer> b = Sets.mutable.with(4, 5, 6);
LazyIterable<Pair<Integer, Integer>> pairs =
Sets.cartesianProduct(a, b);

Eventually I hope we will have all of the methods available on Sets today on the equivalent primitive Sets classes. There are methods like difference, symmetricDifference, powerSet, etc. on the Sets class today. Cartesian Product was a good first step to providing better symmetry for primitive collections.

…and there is more. See the detailed release notes here.

I am a Project Lead and Committer for the Eclipse Collections OSS project at the Eclipse Foundation. 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