Sitemap

My Ten Year Quest to Evolve Java Collections Beyond Java Stream

11 min readSep 7, 2026

--

Java Stream was hot magma in Java 8, but its lava flow is hardening.

Press enter or click to view image in full size
Photo by Tetiana GRY on Unsplash

Java Collections are Hardened

Java isn’t getting a new collections library any time soon. After working on Eclipse Collections for over 22 years, the only viable option for me to evolve Java collections is to continue working on Eclipse Collections. If you want a more capable collections library in Java in 2026, your only option may be to choose from the open source alternatives available.

The rest of this blog will explain a bit of history of how we got here, and why Eclipse Collections may be the best possible answer to the future of collections for Java and other JVM languages.

Why and How Eclipse Collections Happened

Eclipse Collections started off originally as GS Collections which was open sourced by Goldman Sachs under an Apache 2.0 license on GitHub in January 2012.

In May 2014, I gave a talk on GS Collections at a JCP Executive Committee Meeting which was hosted at a Goldman Sachs office in London. After the talk, I began conversations on ways to evolve GS Collections in open source to allow contributions from non-Goldman Sachs developers. The result of these conversations would turn into the Eclipse Collections project at the Eclipse Foundation at the end of 2015.

The primary goals of Eclipse Collections were as follows:

  1. Allow anyone to contribute to Eclipse Collections.
  2. Enable Eclipse Collections code to be leveraged in OpenJDK

The second goal is why Eclipse Collections is dual licensed under EPL 1.0 and EDL 1.0. The Eclipse Public License (EPL) 1.0 is not compatible with GPL 2.0. The Eclipse Distribution License (EDL) 1.0 is compatible with the GPL 2.0 license. EDL 1.0 is a BSD 3-Clause license.

In 2015, I believed this would be the best way to grow an open source community around Eclipse Collections and provide a path for any collections improvements to find their way in to the OpenJDK.

Some ideas and experience made it into OpenJDK quietly, but it wasn’t a direct port of Eclipse Collections code to the JDK.

Free Pool Table Looking for Experienced Players

Never play pool with someone who brings their own table.

When lambdas arrived in Java 8 in March 2014, GS Collections already had hundreds of interfaces/classes, hundreds of functional methods, and many thousands of production usages across applications and libraries in Goldman Sachs. The Java community was just beginning to learn functional patterns and how to use Java Stream with lambdas. Developers I worked with and trained in Goldman Sachs already had ten years of experience using advanced collection iteration patterns. They just needed the Java language syntax upgrade with lambdas.

I told the story of waiting ten years for lambdas in Java in the following blog.

When lambdas first came out, I could school any developer using Java Stream with the pool table I had created in 2004. This pool table had the benefits of ten years of engineering calendar time, with tens of contributors, and hundreds of users and applications inside of Goldman Sachs. It also had the wisdom of my Smalltalk experience from the 1990s, backed by the ancient wisdom of the Smalltalk gurus who came before me.

Goldman Sachs shared this pool table with the open source community in 2016, when it moved GS Collections to the Eclipse Foundation. The pool table is open. It can be yours. You can use it and contribute to it. It is free as in speech. You just have to make a choice to include a third-party dependency and write more concise, readable, and efficient code.

The Hardening of a Lava Flow

Since 2016, there are few compelling reasons to stick with just Java collections. Java collections have long begun the process of fossilization. Java Collections hardened from molten lava to porous rock in Java 5, when generics were added to the language. Some new rock climbing gear was bolted onto existing Java collections interfaces in Java 8 using default methods. The greatest advance in the Java Collection API in Java 8 was the addition of the .stream() method, which opened a new world of functional capabilties via the Stream interface. Backwards compatibility concerns kept Java collections mostly locked in solid rock.

Today, Java developers have access to one of the most comprehensive JVM collections libraries available with Eclipse Collections. Every JVM language can leverage Eclipse Collections. I’ve used Eclipse Collections in Java, Kotlin, Scala, and Groovy. All it takes is a choice to include a third-party dependency.

The need to avoid third party dependencies can be a valid concern, but as a general rule, this can be restrictive to the point that any sacrifice you are making by not using it may outweigh the concern.

Are You Fossilized in a Java 8 coding style?

Java 8 was super hot magma for Java developers in 2014. In my estimation, Java 8 saved the Java language from becoming more like COBOL. Java 8 was a Trojan Horse for all the Java doubters and haters. Java found new ways to evolve hardened interfaces “safely” via default methods. Java developers had new ways of writing code to solve problems. They were learning new abstractions like lambdas and lazy iteration patterns, and terminal operations, and how to extend collections via Collectors. This new found set of features was absolutely glorious for many developers. Programming in Java was fun again. Blogs, conference talks, open source libraries, and books exploded onto the scene focused on lambdas and Stream. Developers are still writing actively about Java lambdas and Stream today. Java survived and thrived. But there is a catch.

Java took a shortcut with collections by adding Stream. It was a good shortcut, and a solid bet, that has paid off well for over a decade. Shortcuts only help you for some time. The sell-by date on the Stream shortcut is at least five years past due. Java has hardened its collections library for almost three decades. Default method additions to Java collection types over the years have been much needed catchup, but not compelling reasons to upgrade to new versions of Java after Java 8.

Java Collection Evolution

The following is a chart that appears in Appendix B of the book, “Eclipse Collections Categorically”, which shows where the major Java Collection interfaces have evolved since Java 8. One of the new methods on List, Set, and Map have the same name with multiple overloads, so are only counted once. The new method is the static of factory method. List also received a bunch of new default methods via the SequencedCollection interface introduced in Java 21 (e.g. getFirst, getLast, etc.).

Press enter or click to view image in full size
Methods added to Java Collection Interfaces before and after Java 8

Java Stream Evolution

The following is a chart that appears in Appendix B of the book, “Eclipse Collections Categorically”, which shows where the major Java Stream interfaces have evolved since being introduced in Java 8. There are more behaviors on Java Stream than there are on Java Collection, because it was new and didn’t have to worry about breaking existing clients.

Press enter or click to view image in full size
Methods added to Java Stream types in Java 8 and after Java 9

Refactoring to Eclipse Collections

If you want to see what refactoring from Java Collection/Stream to Eclipse Collections looks like in practice, the following blog is a great resource.

This blog also has an up to date Venn diagram showing currently available methods on Java Stream, Collectors, Gatherers, Set, Collections as of Java 25. The book “Eclipse Collections Categorically” covered up through Java 21, which is what was available at the time of writing.

Get Donald Raab’s stories in your inbox

Join Medium for free to get updates from this writer.

Read on to find out a limited time free offer to get access to these and other useful tables and charts in the Appendices of “Eclipse Collections Categorically.”

Java Wants to Evolve and for You to Upgrade

Let’s be honest. No one wants to rest on their amazing work and maintain it for decades. Everyone wants evolution, and hot magma features that send everyone into a frenzy of learning and experimentation. JVM vendors also like to continue to sell support.

The trick is to figure out how to roll out new features and get folks excited to adopt “the new hot magma” in the next Java release. Java has done pretty well at this, since it introduced the six month release cycle over 15 Java versions ago.

Java Collection is not the place to look for many new features. If you want to understand why, read this question and answer on StackOverflow.

It is safer for everyone in the Java Community if the existing Collection interfaces don’t evolve. Move predictably, release regularly, and don’t break stuff that works.

Changing existing interfaces is not the only way to evolve. Eclipse Collections has proven that for over two decades. There is a way for the existing Java Collections framework to evolve safely without touching the existing interfaces. Read on to learn how.

New Features Aren’t Solving the Hardened Problem

Java Stream has been referred to as “Java collections 1.5.” Stream was a nice way to add declarative functional behaviors to collections and other things (e.g. files) to provide just-in-time support for lambdas. Stream was a reasonable approach to enable Java developers to safely have access to lambdas and to be able to use them with easily with all their existing code.

For Eclipse Collections, Stream was a nice “free” addition, but we already everything we ever needed for enabling lambdas in a collections API. Java Collection on the other hand, did not, and most likely will not have the same level of features as Eclipse Collections.

It is great that all the code that has ever been written that uses Java Collection still works today. For some, this hasn’t been as rosy a story as you might expect. Eclipse Collections has had to fix multiple compatibility breaks with Java over the years. We look at this as a reasonable challenge to address so the whole Java community can move forward. This is why Eclipse Collections participates in the OpenJDK Quality Outreach Program.

Sometimes You Have to Break Some Eggs

The Java Time library is a good example of having to move on from something that was severely flawed and painful to use. Java Time gave an alternate solution that fixed what was wrong with Java Date and Calendar. The two solutions do not have much in common, other than they work with dates and times.

I have previously proposed to the Java Community Process Executive Committee (JCP EC), one way to “safely” evolve the existing Java Collections library, without needing to abandon the existing interfaces. No, I have not proposed just taking Eclipse Collections and including it in the JDK, but that could certainly be one approach. I proposed another way back in April 2020. I even built a fully working prototype to show how it could work. The prototype code is available in open source. Find the link to the OSS repo in the deck that follows.

The following is a deck I presented to the JCP Executive Committee in April 2020. It is permanently available linked in the online JCP EC meeting minutes at jcp.org for April 2020. This deck was a proposal to the EC to garner support for creating a Java Collections 2.0 JSR.

This strategy is informed from now 22 years of having brought my own pool table to the Java ecosystem to play pool. The prototype borrows design ideas from Eclipse Collections, and combines them with the naming strategies of Java Stream that most Java developers have become very familiar with (e.g. filter, map, reduce).

Java Stream is Showing its Age

I also wrote on Medium in February 2020 about the need for a new collections library evolution for Java. Eclipse Collections has continued to evolve and solve new problems.

Java Stream has been around for twelve years now, and it has many opportunities for improvement and optimizations. The reference implementation of Stream (ReferencePipeline$Head) has not really seen any competitive alternatives, that I am aware of anyway. If there was a competitive alternative, we might have already started using it as a replacement for our Stream implementation in Eclipse Collections.

I have been blogging for the past six months about opportunities for improvement I have been seeing in Java Stream. The following blog contains a set of links of all the optimization discoveries and opportunities I have shared with the community.

What About Project Valhalla?

If you’re waiting patiently to be able to replace List<Integer> with List<int> in your code base to enjoy optimizations that have been available in Eclipse Collections since 2012, then you are more patient than me. I have been enjoying replacing List<Integer> with IntList and MutableIntList and ImmutableIntList for almost 15 years.

While we might eventually be able to say List<int> in our code, the List interface will not be magically expanded to have 174 additional functional methods. It will have what it has had since Java 21 when a whole bunch of new first/last methods were added.

There is no plan, that I am aware of, for Valhalla to bring with it any substantial changes to the Java collections interfaces. They are still locked in hardened rock, and will likely be that way forever. This is a necessary tradeoff for stability, predictability, and reliability in Java.

There are alternatives to Java collections. Eclipse Collections is one of the alternatives that provides direct integration and support for the existing Java Collection and Stream libraries.

Move Along Now, It’s Time

We’re not going to get a new Java Collections framework in the JDK. I’ve moved along and am no longer trying to convince anyone of the possibilities of evolving the standard Java collections. We already have access to one of the most comprehensive JVM collections frameworks via Eclipse Collections. You just have to make the decision to include it in your projects and use it. Eclipse Collections continues to evolve and grow with contributions from over a hundred developers in open source.

Free yourself from the hardened lava flow path of Java collections. Break your application code out of its fossilized Java 8 shell and try something more evolved and feature-rich. Every Java developer that I know that has used Eclipse Collections, rarely if ever goes back to just using standard Java collections. I say “just using” because Eclipse Collections has great compatibility and interop with Java Collection types including Iterable, Collection, List, Set, Map, Stream. You can start with your level of familiarity using standard JDK interfaces, and grow at your own pace to using Eclipse Collections interfaces and iteration patterns.

Try out the free Eclipse Collections pool table, and level up your Java collections pool game.

Thanks for reading, and since you read this far, please check out the limited time free Kindle book offer.

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 the author of the book, Eclipse Collections Categorically: Level up your programming game.

--

--