I have a hash map. Multiple keys have same value. What is the best way to find the
keys for repeated Values
without iterating. ?
Reading this documentation it feels there is no function for it.
NOTE: Key | Value pair are of Int type
I have a hash map. Multiple keys have same value. What is the best way to find the
keys for repeated Values
without iterating. ?
Reading this documentation it feels there is no function for it.
NOTE: Key | Value pair are of Int type
There is no way to find all the keys for a value without iterating on the Map in standard JDK API.
You can use the Guava library, either by :
One way or the other, you will end up iterating the collection. The iteration may be hidden from view in some library, but it would necessarily be there.
You can easily write a simple method that does what you need:
public static <K,V> Set<K> keysOfDupValues(Map<K,V> m) {
Set<K> res = new HashSet<K>();
Map<V,K> seen = new HashMap<V,K>();
for (Map.Entry<K,V> e : m.entrySet()) {
V v = e.getValue();
K k = e.getKey();
if (seen.containsKey(v)) {
res.add(k);
res.add(seen.get(v));
} else {
seen.put(v, k);
}
}
return res;
}
It's really not possible. The very implementation of method containsValue()
, in the superclass java.util.AbstractMap
iterates through the values.
So, you'll have to itarate through the values to achieve that.
You can take a look at the implementation of containsValue()
to have a hint on how to do that.
If you get that map read made from code you don't have control on, then you have no other choice but to iterate on the map.
In any case, you can avoid the issue of doing several iterations by building a reverse map, which will boil down to a multimap, but since there is no specific class definition for that pattern in Java, you will have to build it using a map and lists.
Each time you need to include a new pair <k,v>
in your original map, you also include the reverse pair <v,k>
in your reverse map. If v
as a key (ie. the original value) doesn't yet exist in the reverse map, you map it to a list solely containing k
as the value (ie. the original key). If the key v
already exists in the reverse map, then you simply push the value k
to the existing list.
When you need to know which keys map to a given value in your original map, you query for the value in the reverse map, and get the list of keys.
The Java tutorial on maps includes a section on implementing multimaps using maps.
This solution should be very effective if you have control on the map creation process. However, if the map is created and regularily updated by some outside mechanism, it will be of little gain.
If you can only control the creation of the map, but not its update, you could implement a new class exposing the Map
interface, which internally holds the reverse map as well and update it when a new pair is inserted/removed, or support a notification mechanism to let your code know the map has been changed and how.
Try change
File newxmlfile = new File(Environment.getExternalStorageDirectory()
+ ts);
to
File newxmlfile = new File(Environment.getExternalStorageDirectory()
+ "/"+ts);