Bi-directional Map in Java?

117,612

Solution 1

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

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

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

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

Apache commons collections has a BidiMap

Share:
117,612

Related videos on Youtube

Danijel
Author by

Danijel

Audio digital signal processing... and all the things around it.

Updated on October 06, 2020

Comments

  • Danijel
    Danijel over 3 years

    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.

  • mlathe
    mlathe about 10 years
    only works if your Key and Value are the same, or possibly if you use Map<Object, Object>
  • Chicowitz
    Chicowitz about 10 years
    edited for clarification, thanks
  • Mert Mertce
    Mert Mertce about 10 years
    Furthermore, all keys and values should be different.
  • Sibin John Mattappallil
    Sibin John Mattappallil over 7 years
  • Gewure
    Gewure about 7 years
    This answer is pure blasphemy. thats why i like it :)
  • Kanagavelu Sugumar
    Kanagavelu Sugumar almost 6 years
    Like BidiMap bidiMap = new DualHashBidiMap();
  • Ben
    Ben almost 5 years
    This a great hack
  • Kanagavelu Sugumar
    Kanagavelu Sugumar over 4 years
    But this dont have generic support :(
  • Richard Rast
    Richard Rast over 4 years
    For future readers -- this does have generics support at this point
  • MasterJoe
    MasterJoe almost 4 years
    Google probably needs BiMap for specific use cases. But, why does Java not provide BiMap ? Its nice to have options in data structures & algorithms instead of having to get them from libraries or coding from scratch.
  • Guildenstern
    Guildenstern over 3 years
    How does this example illustrate that it is “not so trivial”?