Bi-directional Map in Java?
JavaMapGuavaApache CommonsJava Problem Overview
I have a simple integer-to-string mapping in Java, but I need to be able to easily retrieve string from integer, and also integer from string. I've tried Map, but it can retrieve only string from integer, it's one way:
private static final Map<Integer, String> myMap = new HashMap<Integer, String>();
// This works one way:
String myString = myMap.get(myInteger);
// I would need something like:
Integer myInteger = myMap.getKey(myString);
Is there a right way to do it to have it both directions?
Another problem is that I only have a few constant values that don't change (1->"low", 2->"mid", 3->"high"
, so it wouldn't be worth to go for a complicated solution.
Java Solutions
Solution 1 - Java
You can use the Google Collections API for that, recently renamed to Guava, specifically a BiMap
> A bimap (or "bidirectional map") is a map that preserves the > uniqueness of its values as well as that of its keys. This constraint > enables bimaps to support an "inverse view", which is another bimap > containing the same entries as this bimap but with reversed keys and > values.
Solution 2 - Java
Creating a Guava BiMap and getting its inverted value is not so trivial.
A simple example:
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
public class BiMapTest {
public static void main(String[] args) {
BiMap<String, String> biMap = HashBiMap.create();
biMap.put("k1", "v1");
biMap.put("k2", "v2");
System.out.println("k1 = " + biMap.get("k1"));
System.out.println("v2 = " + biMap.inverse().get("v2"));
}
}
Solution 3 - Java
There is no bidirectional map in the Java Standard API. Either you can maintain two maps yourself or use the BidiMap from Apache Collections.
Solution 4 - Java
You could insert both the key,value pair and its inverse into your map structure, but would have to convert the Integer to a string:
map.put("theKey", "theValue");
map.put("theValue", "theKey");
Using map.get("theValue") will then return "theKey".
It's a quick and dirty way that I've made constant maps, which will only work for a select few datasets:
- Contains only 1 to 1 pairs
- Set of values is disjoint from the set of keys (1->2, 2->3 breaks it)
If you want to keep <Integer, String>
you could maintain a second <String, Integer>
map to "put" the value -> key pairs.
Solution 5 - Java
Apache commons collections has a BidiMap
Solution 6 - Java
Use Google's BiMap
It is more convenient.