What are the reasons behind the decision to not have a fully generic get method in the interface of java.util.Map<K, V>
.
To clarify the question, the signature of the method is
V get(Object key)
instead of
V get(K key)
and I'm wondering why (same thing for remove, containsKey, containsValue
).
Before ES6, we often used an object to emulate a map by mapping a key to a value of any type. But using an object as a map has some side effects: An object always has a default key like the prototype. A key of an object must be a string or a symbol, you cannot use an object as a key.
If the key is not present in the map, get() returns null. The get() method returns the value almost instantly, even if the map contains 100 million key/value pairs.
The term generic simply is the idea of allowing the type (Integer, Double, String, etc. or any user-defined type) to be the parameter to methods, class, or interface. For eg, all the inbuilt collections in java like ArrayList, HashSet, HashMap, etc. use generics.
Therefore, to use an object as a key in HashMap , HashSet , or Hashtable in Java, we need to override equals and hashcode methods of that object since default implementation of these methods simply check for the instance equality.
As mentioned by others, the reason why get()
, etc. is not generic because the key of the entry you are retrieving does not have to be the same type as the object that you pass in to get()
; the specification of the method only requires that they be equal. This follows from how the equals()
method takes in an Object as parameter, not just the same type as the object.
Although it may be commonly true that many classes have equals()
defined so that its objects can only be equal to objects of its own class, there are many places in Java where this is not the case. For example, the specification for List.equals()
says that two List objects are equal if they are both Lists and have the same contents, even if they are different implementations of List
. So coming back to the example in this question, according to the specification of the method is possible to have a Map<ArrayList, Something>
and for me to call get()
with a LinkedList
as argument, and it should retrieve the key which is a list with the same contents. This would not be possible if get()
were generic and restricted its argument type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With