mawia
mawia

Reputation: 9349

Bidirectional Map

Can you suggest a kind of map or similar data structure where we can get both the value and key from each other at equal ease. That is to say, that each may be used to find other.

Upvotes: 71

Views: 29619

Answers (9)

Simeon
Simeon

Reputation: 818

Based on this tutorial I suggest the following as answer:

public class IdToNames {
  public static void main(String[] args){
    BidiMap<String, Integer> map = new DualHashBidiMap<>();

    map.put("NameA", 100);
    map.put("NameB", 200);

    System.out.println(map.size()); //2 as expected
    System.out.println(map.get("NameA")); //100 as expected
    System.out.println(map.getKey(100)); //"NameA" as expected
  }
}

Note the problem of duplicated keys and/or values described in this question here

Upvotes: 1

Davut G&#252;rb&#252;z
Davut G&#252;rb&#252;z

Reputation: 5756

Based on this answer in this QA and its comments I wrote following. [Will be tested]

Bidirectional Map

import java.util.HashMap;

public class BidirectionalMap<K, V> extends HashMap<K, V> {
private static final long serialVersionUID = 1L;
public HashMap<V, K> inversedMap = new HashMap<V, K>();

public K getKey(V value) {              
    return inversedMap.get(value);
}

@Override
public int size() {
    return this.size();
}

@Override
public boolean isEmpty() {
    return this.size() > 0;
}

@Override
public V remove(Object key) {
    V val=super.remove(key);
    inversedMap.remove(val);
    return val;
}

@Override
public V get(Object key) {
    return super.get(key);
}

@Override
public V put(K key, V value) {      
    inversedMap.put(value, key);
    return super.put(key, value);
}

}

Upvotes: 3

You can define an enum and define helper method to get key. Performance is way too far better compared to BidiMap. E.g

public enum Fruit {
        APPLE("_apple");
        private final String value;
        Fruit(String value){
            this.value=value;
        }
        public String getValue(){
            return this.value;
        }
        public static String getKey(String value){
            Fruit fruits[] = Fruit.values();
            for(Fruit fruit : fruits){
                if(value.equals(fruit.value)){
                    return fruit.name();
                }
            }
            return null;        }
    }

Upvotes: 0

Jesper
Jesper

Reputation: 206996

Java doesn't have a bidirectional map in its standard library.

Use for example BiMap<K, V> from Google Guava .

Upvotes: 49

Buhake Sindi
Buhake Sindi

Reputation: 89199

Google Guava contains a BiMap (BiDirectional Map).

Upvotes: 6

Rohit Sharma
Rohit Sharma

Reputation: 13825

If you feel it pain importing some third party library. How about this simple class.

public class BiMap<K,V> {

    HashMap<K,V> map = new HashMap<K, V>();
    HashMap<V,K> inversedMap = new HashMap<V, K>();

    void put(K k, V v) {
        map.put(k, v);
        inversedMap.put(v, k);
    }

    V get(K k) {
        return map.get(k);
    }

    K getKey(V v) {
        return inversedMap.get(v);
    }

}

Make sure K and V class has proper hashCode implementation.

Upvotes: 37

Gregor
Gregor

Reputation: 1296

well for the average usecase where you need a Dictionary like that, I see nothing wrong with a KISS solution, just put'ting the key and value vice versa, saving the overhead of a second Map or even library only for that purpose:

myMap.put("apple", "Apfel");
myMap.put("Apfel", "apple");

Upvotes: 4

kervin
kervin

Reputation: 11858

Also try Apache Commons Collections 4 BidiMap Package.

Upvotes: 11

Joni
Joni

Reputation: 111389

The most common solution is using two maps. You can easily encapsulate them in a class with a friendly interface by extending AbstractMap. (Update: This is how Guava's HashBiMap is implemented: two maps)

Creating a new data structure using nothing but arrays and custom classes has few advantages. The map implementations are lightweight wrappers of a data structure that indexes the keys. Since you need two indexes you might as well use two complete maps.

Upvotes: 14

Related Questions