Search code examples
javadictionaryhashmapimmutabilityjava-9

Is the Access Time Complexity of a Map Created by Map.ofEntries() the Same as HashMap which is o(1)?


I wanted to create an immutable hashMap inline using the new factory method Map.ofEntries() in Java 9, for example:

Map<Integer, String> map = Map.ofEntries(
    Map.entry(1, "One"),
    Map.entry(2, "Two"),
    Map.entry(3, "Three"));

Then to my surprise, I found I could not create an immutable hashMap the same way! For example, the following code would not work.

HashMap<Integer, String> map = HashMap.ofEntries( //not work
    Map.entry(1, "One"),
    Map.entry(2, "Two"),
    Map.entry(3, "Three"));

Then when I want to check what type of map is returned by the factory method, I found the following note:

Callers should make no assumptions about the identity of the returned instances.

So my question is, is the access time complexity of an immutable map the same as a hashMap which is o(1)? If not, how to create a map that is both immutable and access o(1) at the same time? It would be best if it can be created inline.


Solution

  • Mutability or immutability are not directly related to the complexity of the access operation in a Map. For instance, a HashMap will always be O(1) for the get() operation, whereas a TreeMap will be O(log n). It's the implementing class of the Map interface that determines the complexity of the operations.

    Besides it's always been possible to create unmodifiable maps, because we can make any Map of any concrete type immutable after we put items on it, like this:

    Map<Integer, String> immutableMap = Collections.unmodifiableMap(mutableMap);
    

    To be clear, HashMap.ofEntries() won't work because the ofEntries() method is static and defined in the Map interface, not in any of its implementing classes.

    And you should not worry about being unable to declare the type of a map as HashMap or some other concrete class, anyway the best practice is to declare the map as being of a Map interface.

    Also, if you were using a version older than Java 9 and don't mind using an external library, you can use ImmutableMap from Guava:

    Map<Integer, String> immutableMap = ImmutableMap.of(key1, val1, key2, val2);
    

    Perhaps reading this article will clarify things a bit more.