tl;dr
Use Map.of…
methods in Java 9 and later.
Map< String , String > animalSounds =
Map.of(
"dog" , "bark" , // key , value
"cat" , "meow" , // key , value
"bird" , "chirp" // key , value
)
;
Map.of
Java 9 added a series of Map.of
static methods to do just what you want: Instantiate an immutable Map
using literal syntax.
The map (a collection of entries) is immutable, so you cannot add or remove entries after instantiating. Also, the key and the value of each entry is immutable, cannot be changed. See the Javadoc for other rules, such as no NULLs allowed, no duplicate keys allowed, and the iteration order of mappings is arbitrary.
Let's look at these methods, using some sample data for a map of day-of-week to a person who we expect will work on that day.
Person alice = new Person( "Alice" );
Person bob = new Person( "Bob" );
Person carol = new Person( "Carol" );
Map.of()
Map.of
creates an empty Map
. Unmodifiable, so you cannot add entries. Here is an example of such a map, empty with no entries.
Map < DayOfWeek, Person > dailyWorkerEmpty = Map.of();
dailyWorkerEmpty.toString(): {}
Map.of( … )
Map.of( k , v , k , v , …)
are several methods that take 1 to 10 key-value pairs. Here is an example of two entries.
Map < DayOfWeek, Person > weekendWorker =
Map.of(
DayOfWeek.SATURDAY , alice , // key , value
DayOfWeek.SUNDAY , bob // key , value
)
;
weekendWorker.toString(): {SUNDAY=Person{ name='Bob' }, SATURDAY=Person{ name='Alice' }}
Map.ofEntries( … )
Map.ofEntries( Map.Entry , … )
takes any number of objects implementing the Map.Entry
interface. Java bundles two classes implementing that interface, one mutable, the other immutable: AbstractMap.SimpleEntry
, AbstractMap.SimpleImmutableEntry
. But we need not specify a concrete class. We merely need to call Map.entry( k , v )
method, pass our key and our value, and we get back an object of a some class implementing Map.Entry
interface.
Map < DayOfWeek, Person > weekdayWorker = Map.ofEntries(
Map.entry( DayOfWeek.MONDAY , alice ) , // Call to `Map.entry` method returns an object implementing `Map.Entry`.
Map.entry( DayOfWeek.TUESDAY , bob ) ,
Map.entry( DayOfWeek.WEDNESDAY , bob ) ,
Map.entry( DayOfWeek.THURSDAY , carol ) ,
Map.entry( DayOfWeek.FRIDAY , carol )
);
weekdayWorker.toString(): {WEDNESDAY=Person{ name='Bob' }, TUESDAY=Person{ name='Bob' }, THURSDAY=Person{ name='Carol' }, FRIDAY=Person{ name='Carol' }, MONDAY=Person{ name='Alice' }}
Map.copyOf
Java 10 added the method Map.copyOf
. Pass an existing map, get back an immutable copy of that map.
Notes
Notice that the iterator order of maps produced via Map.of
are not guaranteed. The entries have an arbitrary order. Do not write code based on the order seen, as the documentation warns the order is subject to change.
Note that all of these Map.of…
methods return a Map
of an unspecified class. The underlying concrete class may even vary from one version of Java to another. This anonymity enables Java to choose from various implementations, whatever optimally fits your particular data. For example, if your keys come from an enum, Java might use an EnumMap
under the covers.
static
while this Question is asking about instantiating by literal syntax. Voting to re-open. Perhaps this Question is a duplicate of some other Question; if so, re-open and close again by linking to a Question that is truly an original of this. – Basil Bourque