You cannot retrieve the original key from a HashMap
, without just doing a brute-force sequential search like this:
K keyToLookup = ...;
K originalKey = map.keySet().stream().filter(keyToLookup::equals).findAny().orElse(null);
Option 1: Embed key in value
Workaround for a HashMap
is of course to have the key object as part of the value:
By actually having the key object as part of the value object, which is often inherent, e.g. a map of user name to user object. May require modifying the value object, and may require removing and re-adding the map entry when it is updated to refer to a different value object.
In a separate Map<K, K>
. Less efficient, since you have to look up twice.
By changing the value to a key/value pair, e.g. Map<K, Entry<K, V>>
. This is likely the best solution, but does require care to ensure that the Entry's key object is always the original key.
Option 2: Use NavigableMap
If the Map
can be changed from a HashMap
to be a NavigableMap
, e.g. a TreeMap
, it supports retrieving the original key object from the map, e.g. using the ceilingEntry(K key)
method.
The key object must implement Comparable
or the TreeMap
can use a custom Comparator
. In either case, the implementation must be consistent with equals.
Not all key types can define a relative ordering, so it may not be possible to use NavigableMap
.
K keyToLookup = ...;
Entry<K,V> entry = map.ceilingEntry(keyToLookup);
if (entry != null && entry.getKey().equals(keyToLookup)) {
K originalKey = entry.getKey();
V value = entry.getValue();
// code here
} else {
// key not found
}