web-dev-qa-db-fra.com

Carte bidirectionnelle

Pouvez-vous suggérer une sorte de carte ou une structure de données similaire dans laquelle nous pouvons obtenir à la fois la valeur et la clé les uns des autres. C'est-à-dire que chacun peut être utilisé pour en trouver un autre.

43
mawia

Java n'a pas de carte bidirectionnelle dans sa bibliothèque standard.

Utilisez par exemple BiMap<K, V> from Google Guava .

32
Jesper

Si vous sentez qu'il est difficile d'importer une bibliothèque tierce .. 

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);
    }

}

Assurez-vous que les classes K et V ont une implémentation correcte de hashCode.

19
Javanator

La solution la plus courante consiste à utiliser deux cartes. Vous pouvez facilement les encapsuler dans une classe avec une interface conviviale en développant AbstractMap. ( Mise à jour: Voici comment la HashBiMap de Guava est implémentée: deux cartes)

La création d'une nouvelle structure de données à l'aide de tableaux et de classes personnalisées présente peu d'avantages. Les implémentations de carte sont des wrappers légers d’une structure de données qui indexe les clés. Comme vous avez besoin de deux index, vous pouvez également utiliser deux cartes complètes.

11
Joni

Essayez également Apache Commons Collections 4 BidiMap Package.

7
kervin

Google Guava contient une BiMap (carte bidirectionnelle). 

5
Buhake Sindi

bien pour la moyenne des cas où vous avez besoin d’un dictionnaire comme celui-ci, je ne vois aucun problème avec une solution KISS, il suffit de mettre la clé et la valeur inversement, ce qui évite les frais généraux d’une deuxième carte ou même d’une bibliothèque uniquement objectif:

myMap.put("Apple", "Apfel");
myMap.put("Apfel", "Apple");
1
Gregor

Vous pouvez définir une méthode énumérée et définie d'assistance pour obtenir la clé. Les performances sont bien meilleures que 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;        }
    }
0

Basé sur cette réponse dans ce QA et ses commentaires, j’ai écrit ci-dessous [Sera testé)

Carte bidirectionnelle

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);
}

}
0
Davut Gürbüz