Because final marks the reference, not the object. You can't make that reference point to a different hash table. But you can do anything to that object, including adding and removing things.

Your example of an int is a primitive type, not a reference. Final means you cannot change the value of the variable. So, with an int you cannot change the value of the variable, e.g. make the value of the int different. With an object reference, you cannot change the value of the reference, i.e. which object it points to.

Answer from Joe on Stack Overflow
🌐
Coderanch
coderanch.com › t › 517362 › java › final-applied-Map
Why final is not applied for Map ? (Beginning Java forum at Coderanch)
i am sorry you are correct. Actually final applied for all class,variable and method. Got the point. Means applying final in Map .
🌐
Java2s
java2s.com › Tutorials › Java › Collection_How_to › Set › Create_final_HashMap_that_should_not_allow_to_update_or_remove_element.htm
Java Collection How to - Create final HashMap that should not allow to update or remove element
Map · Properties · Queue · Set · Back to Set ↑ · We would like to know how to create final HashMap that should not allow to update or remove element. import java.util.Collections; import java.util.Hashtable; import java.util.Map; // ww w.
🌐
Alvin Alexander
alvinalexander.com › java › how-to-populate-predefined-static-data-map-hashmap-in-java
How to populate static, predefined data in a Map/HashMap in Java | alvinalexander.com
If you need to initialize/populate a Map/HashMap in Java prior to Java 9 — such as when you’re writing Android code — the following source code shows the proper syntax: /** * Off Tackle Run vs 3-4 Defense [Yardage Gained -> Probability] */ public static final Map<Integer, Float> RunOffTackle_34Defense = new HashMap<Integer, Float>() {{ put(-99, 1f); //1 fumble per 100 hand-offs put(-1, 4f); put( 0, 5f); put( 1, 9f); put( 2, 11f); put( 3, 15f); put( 4, 15f); put( 5, 11f); put( 6, 9f); put( 7, 5f); put( 8, 4f); put( 9, 3f); put(10, 3f); put(12, 2f); put(15, 2f); put(20, 1f); }};
Top answer
1 of 16
1202

The instance initialiser is just syntactic sugar in this case, right? I don't see why you need an extra anonymous class just to initialize. And it won't work if the class being created is final.

You can create an immutable map using a static initialiser too:

public class Test {
    private static final Map<Integer, String> myMap;
    static {
        Map<Integer, String> aMap = ....;
        aMap.put(1, "one");
        aMap.put(2, "two");
        myMap = Collections.unmodifiableMap(aMap);
    }
}
2 of 16
493

I like the Guava way of initialising a static, immutable map:

static final Map<Integer, String> MY_MAP = ImmutableMap.of(
    1, "one",
    2, "two"
);

As you can see, it's very concise (because of the convenient factory methods in ImmutableMap).

If you want the map to have more than 5 entries, you can no longer use ImmutableMap.of(). Instead, try ImmutableMap.builder() along these lines:

static final Map<Integer, String> MY_MAP = ImmutableMap.<Integer, String>builder()
    .put(1, "one")
    .put(2, "two")
    // ... 
    .put(15, "fifteen")
    .build();

To learn more about the benefits of Guava's immutable collection utilities, see Immutable Collections Explained in Guava User Guide.

(A subset of) Guava used to be called Google Collections. If you aren't using this library in your Java project yet, I strongly recommend trying it out! Guava has quickly become one of the most popular and useful free 3rd party libs for Java, as fellow SO users agree. (If you are new to it, there are some excellent learning resources behind that link.)


Update (2015): As for Java 8, well, I would still use the Guava approach because it is way cleaner than anything else. If you don't want Guava dependency, consider a plain old init method. The hack with two-dimensional array and Stream API is pretty ugly if you ask me, and gets uglier if you need to create a Map whose keys and values are not the same type (like Map<Integer, String> in the question).

As for future of Guava in general, with regards to Java 8, Louis Wasserman said this back in 2014, and [update] in 2016 it was announced that Guava 21 will require and properly support Java 8.


Update (2016): As Tagir Valeev points out, Java 9 will finally make this clean to do using nothing but pure JDK, by adding convenience factory methods for collections:

static final Map<Integer, String> MY_MAP = Map.of(
    1, "one", 
    2, "two"
);
🌐
Patreon
patreon.com › posts › initialise-map-104504087
Initialise a static Map in Java | Andrey Pyatakha
May 22, 2024 - import java.util.Map; import java.util.Map.Entry; public class Test { private static final Map<Integer, String> myMap = Map.ofEntries( Map.entry(1, "one"), Map.entry(2, "two") ); // Other class members...
🌐
Educative
educative.io › answers › how-to-initialize-a-static-map-in-java
How to initialize a static map in Java
import java.util.Map; class Main · { private static final Map<String, String> immutableMap = initializeMap(); private static Map<String, String> initializeMap() { Map<String, String> map = new HashMap(); map.put("one", "one"); map.put("two", "two"); return Collections.unmodifiableMap(map); } public static void main(String[] args) { System.out.println(immutableMap); } } Run ·
Find elsewhere
🌐
Reddit
reddit.com › r/javahelp › [deleted by user]
Confused with final keyword before hashmap : r/javahelp
August 15, 2023 - It is a best practice to use it mostly everywhere (not necessary for primitives, though) and that's why languages such as Kotlin have variables final by default (Java records try to replicate that, as I see it). Also, final is necessary (but not enough) to achieve immutability. Your map there can be final but the object is still mutable (you can add/remove/alter the map's content).
🌐
GitHub
github.com › kotest › kotest › issues › 3035
SystemEnvironmentTestListener - Unable to make field private final java.util.Map java.util.Collections$UnmodifiableMap.m accessible: · Issue #3035 · kotest/kotest
May 4, 2022 - @Suppress("UNCHECKED_CAST") private fun getEditableMapOfVariables(): MutableMap<String, String> { val systemEnv = System.getenv() val classOfMap = systemEnv::class.java return classOfMap.getDeclaredField("m").asAccessible().get(systemEnv) as MutableMap<String, String> }
Published   Jun 05, 2022
🌐
Oracle
docs.oracle.com › javase › tutorial › collections › implementations › map.html
Map Implementations (The Java™ Tutorials > Collections > Implementations)
For example, this override will allow the map to grow up to as many as 100 entries and then it will delete the eldest entry each time a new entry is added, maintaining a steady state of 100 entries. private static final int MAX_ENTRIES = 100; protected boolean removeEldestEntry(Map.Entry eldest) { return size() > MAX_ENTRIES; }
Top answer
1 of 16
2248

All Versions

In case you happen to need just a single entry: There is Collections.singletonMap("key", "value").

For Java Version 9 or higher:

Yes, this is possible now. In Java 9 a couple of factory methods have been added that simplify the creation of maps :

// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
    "a", "b",
    "c", "d"
);

// this works for any number of elements:
import static java.util.Map.entry;    
Map<String, String> test2 = Map.ofEntries(
    entry("a", "b"),
    entry("c", "d")
);

In the example above both test and test2 will be the same, just with different ways of expressing the Map. The Map.of method is defined for up to ten elements in the map, while the Map.ofEntries method will have no such limit.

Note that in this case the resulting map will be an immutable map. If you want the map to be mutable, you could copy it again, e.g. using mutableMap = new HashMap<>(Map.of("a", "b"));. Also note that in this case keys and values must not be null.

(See also JEP 269 and the Javadoc)

For up to Java Version 8:

No, you will have to add all the elements manually. You can use an initializer in an anonymous subclass to make the syntax a little bit shorter:

Map<String, String> myMap = new HashMap<String, String>() {{
    put("a", "b");
    put("c", "d");
}};

However, the anonymous subclass might introduce unwanted behavior in some cases. This includes for example:

  • It generates an additional class which increases memory consumption, disk space consumption and startup-time
  • In case of a non-static method: It holds a reference to the object the creating method was called upon. That means the object of the outer class cannot be garbage collected while the created map object is still referenced, thus blocking additional memory

Using a function for initialization will also enable you to generate a map in an initializer, but avoids nasty side-effects:

Map<String, String> myMap = createMap();

private static Map<String, String> createMap() {
    Map<String,String> myMap = new HashMap<String,String>();
    myMap.put("a", "b");
    myMap.put("c", "d");
    return myMap;
}
2 of 16
1172

This is one way.

Map<String, String> h = new HashMap<String, String>() {{
    put("a","b");
}};

However, you should be careful and make sure that you understand the above code (it creates a new class that inherits from HashMap). Therefore, you should read more here: http://www.c2.com/cgi/wiki?DoubleBraceInitialization , or simply use Guava:

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);

ImmutableMap.of works for up to 5 entries. Otherwise, use the builder: source.

Map<String, String> map = new ImmutableMap.Builder<String, String>()
.put("a", "a")
.put("b", "b")
.build();
🌐
Oracle
docs.oracle.com › javase › 8 › docs › api › java › util › Map.html
Map (Java Platform SE 8 )
October 20, 2025 - The Map interface provides three collection views, which allow a map's contents to be viewed as a set of keys, collection of values, or set of key-value mappings. The order of a map is defined as the order in which the iterators on the map's collection views return their elements.
🌐
Blogger
minborgsjavapot.blogspot.com › 2014 › 12 › java-8-initializing-maps-in-smartest-way.html
Minborg's Java Pot: Java 8, Initializing Maps in the Smartest Way
The Map shall contain the mapping pairs (or Entries as they are called in Java): 0->"zero", 1->"one", 2->"two", ... , 12->"twelve". The straight forward solution is to declare a Map and then just put() entries into the Map. After that is done, we return an Unmodifiable view of the newly created map like this: protected static Map<Integer, String> imperative() { final Map<Integer, String> numMap = new HashMap<>(); numMap.put(0, "zero"); numMap.put(1, "one"); numMap.put(2, "two"); numMap.put(3, "three"); numMap.put(4, "four"); numMap.put(5, "five"); numMap.put(6, "six"); numMap.put(7, "seven");
🌐
GeeksforGeeks
geeksforgeeks.org › java › final-vs-immutability-java
final vs Immutability in Java - GeeksforGeeks
March 2, 2022 - In Java, we know that String objects ... objects. ... final means that you can't change the object's reference to point to another reference or another object, but you can still mutate its state (using setter methods e....
🌐
GeeksforGeeks
geeksforgeeks.org › java › initialize-a-static-map-using-java-9-map-of
Initialize a static Map using Java 9 Map.of() - GeeksforGeeks
July 12, 2025 - Store it in Map and use. Below is the implementation of the above approach: Example 1: ... // Java program to create a static map using Java 9 import java.util.*; class GFG { // Declaring and instantiating the static map private static Map<String, String> map = Map.of("1", "GFG", "2", "Geek", "3", "GeeksForGeeks"); // Driver code public static void main(String[] args) { System.out.println(map); } } Output: