Skip to content
Brian Burton edited this page Feb 28, 2024 · 38 revisions

Immutable Collections for Java (Javimmutable)


Overview

The Javimmutable Collections library provides a powerful selection of immutable/persistent collection classes designed with performance and ease of integration in mind. These collections are intended to replace the java.util collection classes to provide the thread safety and other benefits of immutability.

The Javimmutable classes are immutable so once a particular collection object has been created it cannot be modified. This means that it can be safely shared throughout a program without the need for synchronization or defensive copying. In fact structure sharing is a theme throughout the library. For example you never actually "create" an empty IList instance. The factory method always returns the single, shared, empty list instance when its called.

However a collection that you can't add or delete from has fairly limited utility. Instead of locking you in once you've created a collection, the JImmutable collections are designed to allow themselves to be easily updated as well. Each collection provides methods for adding and removing elements. These methods create a new collection of the same type while leaving the original collection intact (i.e. the original persists). The data structures used to implement the collections (linked lists, balanced binary trees, and integer tries) allow for almost all of the structure of the original collection to be shared by the new collection. Since all objects within each collection are immutable this sharing is completely safe. The collections are persistent in the functional programming sense. The collections are not persistent in the database sense. All contents are stored in memory at all times.

Each collection class provides adapter methods to create java.util style unmodifiable collections backed by the immutable collection. Unlike the Guava immutable collection classes these adapters do not create defensive copies of all elements from the original collections. They simply access elements within the original collection. If you have code that needs a java.util.Map to do its work you can still use an IMap and simply call it's getMap() method when you need to pass a java.util.Map to your older code.

All of the collections implement the Iterable interface so you can use them in foreach loops directly. They also provide stream() and parallelStream() methods as well as collectors to support a more reactive style of programming. In fact, JImmutable collections work naturally with map/reduce style APIs like Apache Spark, Project Reactor, and RxJava. All collections are serializable so they can be used with libraries that require serialization such as Apache Spark.

The library is designed to have no dependencies on other libraries but it should interact well with others. Standard java interfaces are used where appropriate. Class names were chosen to avoid conflict with Guava's immutable container class names.

Note: Keep in mind that while the collections themselves are immutable the values you choose to store in them might not be. Always use immutable objects as keys and if you use mutable objects as values be aware that they could change between when you add them to a JImmutable and when you retrieve them later.

Wiki Pages

Factory Methods
Collections Overview
List Tutorial
Map Tutorial
Array Tutorial
Comparative Performance
Hash Keys Functional Tropes

Project Status

All production releases undergo stress testing and pass all junit tests. They are considered to be safe for production use by the author. Of course you should evaluate the collections for yourself and perform your own tests before deploying them.

All releases are uploaded to the releases section on GitHub and are also available via Maven in Maven Central. You can add JImmutable Collections to your Maven project by adding a dependency like this to your pom.xml.

The maven releases include source jars for easy reference in your IDE.

Version 2.3.0 is compiled using Java 8 and compatible with Java 8+.

Version 4.0.x is compiled using Java 11 and compatible with Java 11+.

    <dependency>
        <groupId>org.javimmutable</groupId>
        <artifactId>collections</artifactId>
        <version>4.0.1</version>
    </dependency>

Differences from Older Versions

The version of the library described in this page is 4.0.1. The new version includes numerous changes to interface and class names and, though the underlying implementation is the same, is not code compatible with older versions of the library. For information about the older library see the Old API Wiki.

  • Interface names have been changed. JImmutable prefix has been changed to a simple I. For example, JImmutableList is now IList.
  • The single JImmutables class containing static factory methods has been replaced by collection specific factory method classes. These classes are named as the plural form of their corresponding collection's interface name.
  • A new collection, IDeque, has been added. This is similar to IList but offers substantially better performance for single value get, insert, assign, and delete methods. It only allows insertion and deletion at the front and back of the collection.
  • New utility classes Maybe, NotNull, Computation, and Result have been added.

Other Resources

Project Members