Finding Symmetry
Evolving the design of Eclipse Collections through symmetry.
Find the Missing Types
Eclipse Collections has a bunch of new types you will not find in the JDK. These types give developers useful functionality that they need. There is an extra cost to supporting additional container types, especially when you factor in having support for primitive types across these types.
These missing types are important. They help Eclipse Collections return better return types for iteration patterns.
Type Symmetry
Eclipse Collections has pretty good symmetry between object and primitive types.
The missing container types are fixed sized primitive arrays, primitive BiMaps
, primitive Multimaps
, and some of the primitive Intervals
(only IntInterval
exists today). String really only should exist as a primitive immutable collection of either char
or int
. Eclipse Collections has CharAdapter
, CodePointAdapter
and CodePointList
which provide a rich set of iteration protocols that work with Strings
.
API Symmetry
There is still much that can be done to improve the symmetry between the object and primitive APIs. There are some APIs that cannot be replicated without adding new types. For instance, it would be less than desirable to implement a primitive version of groupBy
with the current Multimap
implementations because the only option would be to box the primitive Lists
, Sets
or Bags
. Since there are a large number of APIs in Eclipse Collections, I will only draw attention to some of the major APIs that do not currently have symmetry between object and primitive collections. The following methods are missing on the primitive Iterables
.
groupBy
/groupByEach
countBy
/countByEach
aggregateBy
/aggregateInPlaceBy
partition
reduce
/reduceInPlace
toMap
- All “
With
” methods
Of all the missing APIs on primitive collections perhaps the most subtle and yet glaring difference is the lack of “With
” methods. It is not clear if the “With
” methods would be as useful for primitive collections as they are with object collections. For some usage examples of the “With
” methods on the object collection APIs, read my blog titled “Preposition Preference”. The “With
” methods allow for more APIs to be used with Method References.
This is what the signatures for some of the “With
” methods might look like on IntList
.
<P> boolean anySatisfyWith(IntObjectPredicate<? super P> predicate, P parameter);<P> boolean allSatisfyWith(IntObjectPredicate<? super P> predicate, P parameter);<P> boolean noneSatisfyWith(IntObjectPredicate<? super P> predicate, P parameter);<P> IntList selectWith(IntObjectPredicate<? super P> predicate, P parameter);<P> IntList rejectWith(IntObjectPredicate<? super P> predicate, P parameter);
Default Methods to the Rescue
The addition of default methods in Java 8 has been of tremendous help increasing the symmetry between our object and primitive APIs. In Eclipse Collections 10.x we will be able to leverage default methods even more, as we now have the ability to use container factory classes in interfaces. The following examples show how the default implementations of countBy
and countByWith
has been optimized using the Bags
factory.
default <V> Bag<V> countBy(Function<? super T, ? extends V> function)
{
return this.countBy(function, Bags.mutable.empty());
}default <V, P> Bag<V> countByWith(Function2<? super T, ? super P, ? extends V> function, P parameter)
{
return this.countByWith(function, parameter,
Bags.mutable.empty());
}
More on Eclipse Collections API design
To find out more about the design of the Eclipse Collections API, check out this slide deck and the following presentation.
You can also find a set of visualizations of the Eclipse Collection library in this blog post.
Eclipse Collections is open for contributions. If you like the library, you can let us know by starring it on GitHub.