Categorizing the Methods of Set Types in Eclipse Collections
Breaking large feature-rich interfaces into smaller, easy to learn categories
Set
and Eclipse Collections MutableSet
method countsOpen the door to Java 24
When I wrote the book, Eclipse Collections Categorically: Level up your programming game, I used Java 21 to compile and run the code examples in the book. Now that Java 24 is released, and the Gatherer
feature is no longer a preview feature, I thought I would add it to a Venn Diagram above that compares JDK Set
type with Eclipse Collections MutableSet
type. If you buy the book, you will find the the the Venn Diagrams for List
and MutableList
, Stream
and LazyIterable
, in the Appendix A: Method Categories and Counts. The first Venn Diagram that compares Iterable
and RichIterable
is at the beginning of Chapter 2. The paperback version of the book is available on Amazon here:
As we can see from the Venn Diagram above, Gatherers
adds five new methods that have no overlap with the method names in any of the other types. The new methods in Gatherers
are fold()
, mapConcurrent()
, scan()
, windowFixed()
, windowSliding()
. Eclipse Collections types have access to all of these methods when using Java 24. You don’t have to choose whether you use Eclipse Collections or Stream
with Gatherers
— you can use both!
Note, the method fold()
is similar to the method injectInto()
in Eclipse Collections, and the method windowFixed()
is similar to the method chunk()
. Examples of injectInto()
and chunk()
are included in the book. The biggest difference between these methods can be seen in the following example.
import java.util.List;
import java.util.stream.Gatherers;
import org.eclipse.collections.api.RichIterable;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.factory.Sets;
import org.eclipse.collections.api.list.MutableList;
import org.eclipse.collections.api.set.MutableSet;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
public class GatherersTest
{
// Fold and injectInto are categorized as Aggregating Methods
@Test
public void foldVsInjectInto()
{
ImmutableSet<Integer> set = Sets.immutable.with(1, 2, 3, 4, 5);
String gathered = set.stream()
.gather(Gatherers.fold(() -> "", (s, i) -> s + i))
.findFirst()
.orElse("");
String injected = set.injectInto("", (s, i) -> s + i);
Assertions.assertEquals("12345", gathered);
Assertions.assertEquals(gathered, injected);
}
// WindowFixed and chunk are categorized as Grouping Methods
@Test
public void windowFixedVsChunk()
{
ImmutableList<Integer> list = Lists.immutable.with(1, 2, 3, 4, 5);
List<List<Integer>> gathered = list.stream()
.gather(Gatherers.windowFixed(2))
.toList();
RichIterable<RichIterable<Integer>> chunked = list.chunk(2);
var expected = List.of(List.of(1, 2), List.of(3, 4), List.of(5));
Assertions.assertEquals(expected, gathered);
Assertions.assertEquals(gathered, chunked);
}
}
As we can see, it is less verbose, to use injectInto()
and chunk()
directly on Eclipse Collections types. The Gathers
can run in parallel, so there might be some benefit for some use cases, and you can always use Stream
with gather(Gatherer)
with Eclipse Collections types. There are no direct equivalents of scan
and windowSliding
in Eclipse Collections today. The great thing with Eclipse Collections is that you have options, and can use what works best for your use cases. :-)
Note, I did not include Venn Diagrams or method category bar charts for Set
and MutableSet
, Map
and MutableMap
, or Bag
and MutableBag
in the book. There is a lot of overlap for the methods between these types and RichIterable
. I also did not include Venn Diagrams for the Immutable equivalents of these types. I will include the Venn Diagrams and bar charts for MutableSet
and ImmutableSet
below in this blog.
MutableSet Categorically
Here’s the Venn Diagram for java.util.Set
and MutableSet
:
Categorizing the methods in MutableSet
is pretty straightforward and fun. I did not categorize the methods for MutableSet
in the book, Eclipse Collections Categorically. Since I wrote the book, I have written some code that categorizes collection types with feature-rich APIs. This is handy for quickly drawing diagrams and charts. Chapter 10 in the book covers a method category called Set Operations which is a category that is unique to Set
types in Eclipse Collections. Chapter 10 covers examples of methods that one would expect to exist on a Set
type like union()
, intersect()
, difference()
, symmetricDifference()
, and cartesianProduct()
. These methods do no exist on java.util.Set
. I explain how to implement these methods in the book using java.util.Set
.
Here are all of 173 methods on MutableSet
, grouped categorically.
The other methods included in Set Operations are powerSet()
, unionInto()
, intersectInto()
, differenceInto()
, and symmetricDifferenceInto()
. The methods with the suffix Into
place the results into a target Set
that is passed as a second parameter.
The Converting category is large because there are symmetric converters to both Mutable and Immutable types. All of the converter methods are explained in the book.
ImmutableSet Categorically
Here’s the Venn Diagram for java.util.Set
and ImmutableSet
:
There is a subtle difference between MutableSet
and ImmutableSet
Venn Diagrams. The Set
interface is not wholly contained in ImmutableSet
bubble, as it was with MutableSet
. Why is this? MutableSet
extends java.util.Set
. ImmutableSet
does not extend java.util.Set
. This difference in relationships between these interfaces leads to an interesting difference between the method categories for MutableSet
and ImmutableSet
.
Which category would you guess should be missing from ImmutableSet
, that is included with MutableSet
?
Here are all of 158 methods on ImmutableSet
, grouped categorically.
If you guessed that the category Mutating is missing, you are correct. ImmutableSet
has no mutating methods like add()
and remove()
. All Immutable collection interfaces in Eclipse Collections are contractually immutable, which means they contain no mutating methods in their API. There is a new category named Casting in this chart. The book explains the methods that are included in this category in detail. I will give a little spoiler and tell you the method names are castToSet()
and castToCollection()
. What type do you think these methods return, and why?
If you guessed java.util.Set
and java.util.Collection
, you are correct.
Final Thoughts
Categorizing methods in large feature-rich interfaces is a useful activity for helping developers learn the API. This is one of the primary lessons of the Eclipse Collections Categorically book. If you’re wondering why I don’t just categorize the methods in all of the types in Eclipse Collections source code, like I did the RichIterable
interface, simply put, it is a lot of work! The picture below, which I included in the book in Chapter 2, shows the result for RichIterable
in IntelliJ. I’ve zoomed into the graphic to make it very easy to see the detail. The left and middle examples show how RichIterable
can be browsed in IntelliJ Structure View today with Eclipse Collections 11.1.0. I have categorized the methods using Custom Code Folding Regions in Eclipse Collections 12.x and the right example shows the resulting simplification of an expandable tree view of method categories.
I would prefer to wait for Javadoc to include a method category tag so the tooling will take care of things automagically. Today, I would have to use Custom Code Folding Regions in the source code so that IntelliJ can group methods in Structure view. Then I would have to write the Javadoc summary for all of the methods grouped by method category by hand. This is the most painful part to write. The Custom Code Folding regions is the most painful for a committer to have to review as it will be hard in the diff to tell if I accidentally deleted or changed anything.
It is easy enough for me to produce diagrams and charts today, by running some code and creating the diagrams in a presentation tool. Hopefully you can imagine what the method category tags in Javadoc should be able to produce for us in the future. I really think method categories will be a wonderful addition to the Javadoc toolkit.
If you’re interested in learning more about Eclipse Collections and how to organize a feature-rich library using method categories so it is easier to learn, then I would recommend checking out my new book — Eclipse Collections Categorically: Level up your programming game.
Thanks for reading!
I am the creator of and committer for the Eclipse Collections OSS project, which is managed at the Eclipse Foundation. Eclipse Collections is open for contributions. I am also the author of the book, Eclipse Collections Categorically: Level up your programming game.