I am new to Java generics and have managed to get a getKeyByValue
function working with a HashMap<String, String>
, but I don’t understand how the function declaration can be ambiguous/redundant and still work. For example both of these declaration work but the first does not make a lot of sense to me:
private <T, E> String getKeyByValue(Map<String, E> map, String value) { for (Entry<String, E> entry : map.entrySet()) { if (value.equals(entry.getValue())) { return entry.getKey(); } } return null; }
Example with just <E>
:
private <E> String getKeyByValue(Map<String, E> map, String value) { for (Entry<String, E> entry : map.entrySet()) { if (value.equals(entry.getValue())) { return entry.getKey(); } } return null; }
Advertisement
Answer
For the first sample, the generic format type T
is not used, hence can be removed which brings the implementation to be as you second method implementation.
In the second implementation, the Java Generics use is with no utility as the equals
method (you are calling with a typed parameter E
) for the java.lang.String
class accepts an Object
argument, hence any object would fit in there.
private <E> String getKeyByValue(Map<String, E> map, String value) { for (Map.Entry<String, E> entry : map.entrySet()) { if (value.equals(entry.getValue())) { // there is no type checking needed over the value as it can be any acceptable object return entry.getKey(); } } return null; }
The same method could be rewritten using a ?
wildcard as the formal type since there is no type-bounded operations that are needed over the Map
values:
private String getKeyByValue(Map<String, ?> map, String value) { for (Map.Entry<String, ?> entry : map.entrySet()) { if (value.equals(entry.getValue())) { return entry.getKey(); } } return null; }