Bi-directional Map in Java?

JavaMapGuavaApache Commons

Java 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDanijelView Question on Stackoverflow
Solution 1 - JavaepochView Answer on Stackoverflow
Solution 2 - JavaMichal Z m u d aView Answer on Stackoverflow
Solution 3 - JavaMathias SchwarzView Answer on Stackoverflow
Solution 4 - JavaChicowitzView Answer on Stackoverflow
Solution 5 - JavahageView Answer on Stackoverflow
Solution 6 - JavaBOSSView Answer on Stackoverflow