Home » Java » Preserve ordering with immutable Map?

Preserve ordering with immutable Map?

Posted by: admin December 28, 2021 Leave a comment

Questions:

When using java.util.Map.of(), it does not preserve ordering. Is there a way to have immutable Map which does preserve ordering?

Answers:

I believe what you are looking for is LinkedHashMap.
Linked Hashmap is a like a regular HashMap that preserves insertion order.

###

tl;dr

Make a LinkedHashMap, wrap with a call to Collections.umodifiableMap, as discussed in Unmodifiable View Collections.

Map.of unmodifiable static factory maps

The Map implementation used by Map.of methods is clearly documented in the Javadoc. One of the bullet points makes clear that the keys are not sorted:

Unmodifiable Maps

The iteration order of mappings is unspecified and is subject to change.

So you must use another implementation of Map if need sorting.

SortedMap

By "preserve order" did you mean sorted order?

Java includes the SortedMap interface to define behavior of Map implementations that maintain a total ordering across all its keys.

There are two such implementations bundled with Java: TreeMap and ConcurrentSkipListMap.

Original insertion order preserved

Your Question is not clear, but I would guess that what you meant by "preserve ordering" is that you want the key maintained in the order in which they where added to the map. LinkedHashMap does just that, as mentioned in the correct Answer by randypaq13.

To quote the Javadoc:

… predictable iteration order …

… maintains a doubly-linked list running through all of its entries. This linked list defines the iteration ordering, which is normally the order in which keys were inserted into the map (insertion-order). Note that insertion order is not affected if a key is re-inserted into the map.

Unmodifiable maps

The LinkedHashMap meets your need for original-insertion-order, but not your need for being unmodifiable. For that, use the Collections class with its utility method unmodifiableMap.

Map< String , String > map = new LinkedHashMap<>() ;
map.put( "this" , "that" ) ;
map.put( "other" , "thing" ) ;
Map< String , String > unmodMap = Collections.unmodifiableMap( map ) ;

Be sure to study the documentation on Unmodifiable View Collections to understand their behavior. Click to zoom.


Here is a table giving an overview of all the Map implementations bundled with Java 11.

Table of map implementations in Java 11, comparing their features

###

The following does NOT preserve ordering:

Map.of("a", 1, "b", 2); 

If you want to have an immutable ordered Map, then you must go this roundabout way:

var map = new LinkedHashMap<String, String>();
map.put("a", 1);
map.put("b", 2);
map = Collections.unmodifiableMap(map);

Not very optimal, because you have to create two maps, one for the ordering and the other for being immutable..

###

If Google Guava already exists then
ImmutableMap will please your needs.

  1. Immutability (not an unmodifiable view) and
  2. Iteration order = creation order

More about ImmutableCollection types.