Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use of Map.ofEntries() instead of Map.of()

From the documentation of Map.java -

The Map.of() and Map.ofEntries() static factory methods provide a convenient way to create immutable maps.

But when I already can use overloaded method ...

Map.of("k1","v1","k2","v2","k3","v3"...);

... what is the use of Map.ofEntries which also

returns an immutable map containing keys and values extracted from the given entries and the entries themselves are not stored in the map.

like image 678
Mani Avatar asked Oct 06 '17 08:10

Mani


People also ask

What is map of () in Java?

Map , represents a mapping between a key and a value. More specifically, a Java Map can store pairs of keys and values. Each key is linked to a specific value.

Which method is added to Java 9 map?

Java 9 feature – Map.of() method In Java 9, Map. of() was introduced which is a convenient way to create instances of Map interface. It can hold up to 10 key-value pairs.

Why do we use map entry in Java?

Map. Entry interface in Java provides certain methods to access the entry in the Map. By gaining access to the entry of the Map we can easily manipulate them.

What is the difference between HashMap and map in Java?

HashMap is a non-synchronized class of the Java Collection Framework that contains null values and keys, whereas Map is a Java interface, which is used to map key-pair values.


Video Answer


3 Answers

Any guesses on how would you create a Map of 26 elements?

The primary difference between the two factory methods in Map that you already linked is that :

Map.ofEntries

Returns an immutable map containing keys and values extracted from the given entries (that are not bounded in count)

From the JEP-269:Convenience Factory Methods for Collections:

For larger numbers of entries, an API will be provided that will create a Map instance given an arbitrary number of key-value pairs:

Map.ofEntries(Map.Entry<K,V>...)

While this approach is analogous to the equivalent varargs APIs for List and Set, it unfortunately requires that each key-value pair be boxed. A method for boxing keys and values, suitable for static import, will make this more convenient:

Map.Entry<K,V> entry(K k, V v)

Your assumption about the method .of() from Map is somewhat incorrect probably because while this would compile with Java9:

List<Integer> values = List.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); // note 11 elements here

Set<String> keys = Set.of("z", "o", "tw", "th", "fo", "fi", "si", "se", "e", "n", "te");

This, on the other hand, wouldn't:

Map<String, Integer> map = Map.of("z", 0, "o", 1,
      "tw", 2, "th", 3, "fo", 4, "fi", 5,
      "si", 6, "se", 7, "e", 8, "n", 9, "te", 10); // this would not compile

The reason for that is since there is a varargs implementation for List.of and Set.of but to create a similar API for Map both the keys and values were supposed to be boxed as stated in the JEP as well. So, the same was created using varargs of type Map.entry() as:

Map<String, Integer> map = Map.ofEntries(Map.entry("z",0),
       Map.entry("o",1),Map.entry("t",2)...so on);

Furthermore from the documentation of Map.entry() which is also introduced Since:9 -

Returns an immutable Map.Entry containing the given key and value. These entries are suitable for populating Map instances using the Map.ofEntries() method.

The Entry instances created by this method have the following characteristics:

  • They disallow null keys and values. Attempts to create them using a null key or value result in NullPointerException.

  • They are immutable. Calls to Entry.setValue() on a returned Entry result in UnsupportedOperationException.

  • They are not serializable.

  • They are value-based. Callers should make no assumptions about the identity of the returned instances. This method is free to create new instances or reuse existing ones. Therefore, identity-sensitive operations on these instances (reference equality (==), identity hash code, and synchronization) are unreliable and should be avoided.

which are similar to the characteristics of Immutable Map Static Factory Methods introduced recently.

like image 119
Naman Avatar answered Oct 19 '22 17:10

Naman


Java 9 introduced creating small unmodifiable Collection instances using a concise one line code, for maps the signature of factory method is:

static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3)

This method is overloaded to have 0 to 10 key-value pairs, e.g.

Map<String, String> map = Map.of("1", "first");
Map<String, String> map = Map.of("1", "first", "2", "second");
Map<String, String> map = Map.of("1", "first", "2", "second", "3", "third");

Similarly you can have up to ten entries.

For a case where we have more than 10 key-value pairs, there is a different method:

static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

Here is the usage.

Map<String, String> map = Map.ofEntries(
  new AbstractMap.SimpleEntry<>("1", "first"),
  new AbstractMap.SimpleEntry<>("2", "second"),
  new AbstractMap.SimpleEntry<>("3", "third"));
like image 13
Sachin Thapa Avatar answered Oct 19 '22 17:10

Sachin Thapa


Well it's very simple. Map.of() is not a varargs method. There are only overloaded Map.of() for up to 10 entries. On the other hand, Map.ofEntries() is a varargs method, hence allowing you to specify as many entries as you want.

They could have just added Map.ofEntries() but since many times you only need just a few entries, they also included the Map.of() versions as convenience methods so that you don't need to wrap each key-valur pair inside an Entry.

like image 7
M A Avatar answered Oct 19 '22 17:10

M A