[java] Java Immutable Collections

From Java 1.6 Collection Framework documentation:

Collections that do not support any modification operations (such as add, remove and clear) are referred to as unmodifiable. [...] Collections that additionally guarantee that no change in the Collection object will ever be visible are referred to as immutable.

The second criteria confuses me a bit. Given the first collection is unmodifiable, and assuming that the original collection reference has been disposed away, what are the changes that are referred to in the second line? Is it referring to the changes in the elements held in the collection ie the state of the elements?

Second question:
For a collection to be immutable, how does one go about providing the additional guarentees specified? If the state of an element in the collection is updated by a thread, is it sufficient for immutability that those updates in the state are not visible on the thread holding the immutable collection?

For a collection to be immutable, how does one go about providing the additional guarantees specified?

This question is related to java collections immutability

The answer is


Now java 9 has factory Methods for Immutable List, Set, Map and Map.Entry .

In Java SE 8 and earlier versions, We can use Collections class utility methods like unmodifiableXXX to create Immutable Collection objects.

However these Collections.unmodifiableXXX methods are very tedious and verbose approach. To overcome those shortcomings, Oracle corp has added couple of utility methods to List, Set and Map interfaces.

Now in java 9 :- List and Set interfaces have “of()” methods to create an empty or no-empty Immutable List or Set objects as shown below:

Empty List Example

List immutableList = List.of();

Non-Empty List Example

List immutableList = List.of("one","two","three");

I believe the point here is that even if a collection is Unmodifiable, that does not ensure that it cannot change. Take for example a collection that evicts elements if they are too old. Unmodifiable just means that the object holding the reference cannot change it, not that it cannot change. A true example of this is Collections.unmodifiableList method. It returns an unmodifiable view of a List. The the List reference that was passed into this method is still modifiable and so the list can be modified by any holder of the reference that was passed. This can result in ConcurrentModificationExceptions and other bad things.

Immutable, mean that in no way can the collection be changed.

Second question: An Immutable collection does not mean that the objects contained in the collection will not change, just that collection will not change in the number and composition of objects that it holds. In other words, the collection's list of references will not change. That does not mean that the internals of the object being referenced cannot change.


The difference is that you can't have a reference to an immutable collection which allows changes. Unmodifiable collections are unmodifiable through that reference, but some other object may point to the same data through which it can be changed.

e.g.

List<String> strings = new ArrayList<String>();
List<String> unmodifiable = Collections.unmodifiableList(strings);
unmodifiable.add("New string"); // will fail at runtime
strings.add("Aha!"); // will succeed
System.out.println(unmodifiable);

Pure4J supports what you are after, in two ways.

First, it provides an @ImmutableValue annotation, so that you can annotate a class to say that it is immutable. There is a maven plugin to allow you to check that your code actually is immutable (use of final etc.).

Second, it provides the persistent collections from Clojure, (with added generics) and ensures that elements added to the collections are immutable. Performance of these is apparently pretty good. Collections are all immutable, but implement java collections interfaces (and generics) for inspection. Mutation returns new collections.

Disclaimer: I'm the developer of this


Collection<String> c1 = new ArrayList<String>();
c1.add("foo");
Collection<String> c2 = Collections.unmodifiableList(c1);

c1 is mutable (i.e. neither unmodifiable nor immutable).
c2 is unmodifiable: it can't be changed itself, but if later on I change c1 then that change will be visible in c2.

This is because c2 is simply a wrapper around c1 and not really an independent copy. Guava provides the ImmutableList interface and some implementations. Those work by actually creating a copy of the input (unless the input is an immutable collection on its own).

Regarding your second question:

The mutability/immutability of a collection does not depend on the mutability/immutability of the objects contained therein. Modifying an object contained in a collection does not count as a "modification of the collection" for this description. Of course if you need a immutable collection, you usually also want it to contain immutable objects.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to collections

Kotlin's List missing "add", "remove", Map missing "put", etc? How to unset (remove) a collection element after fetching it? How can I get a List from some class properties with Java 8 Stream? Java 8 stream map to list of keys sorted by values How to convert String into Hashmap in java How can I turn a List of Lists into a List in Java 8? MongoDB Show all contents from all collections Get nth character of a string in Swift programming language Java 8 Distinct by property Is there a typescript List<> and/or Map<> class/library?

Examples related to immutability

Enums in Javascript with ES6 Correct way to push into state array What is difference between mutable and immutable String in java Const in JavaScript: when to use it and is it necessary? Aren't Python strings immutable? Then why does a + " " + b work? String is immutable. What exactly is the meaning? Immutable vs Mutable types Java Immutable Collections Set System.Drawing.Color values Remove specific characters from a string in Python