Двунаправленная карта - PullRequest
       3

Двунаправленная карта

47 голосов
/ 20 марта 2012

Можете ли вы предложить тип карты или аналогичную структуру данных, где мы можем одинаково легко получать и значение, и ключ друг от друга. То есть каждый может быть использован для поиска другого.

Ответы [ 8 ]

38 голосов
/ 20 марта 2012

Java не имеет двунаправленной карты в своей стандартной библиотеке.

Используйте, например, BiMap<K, V> из Google Guava .

21 голосов
/ 05 февраля 2016

Если вам неудобно импортировать какую-то стороннюю библиотеку.Как насчет этого простого класса.

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

}

Убедитесь, что классы K и V имеют правильную реализацию hashCode.

13 голосов
/ 20 марта 2012

Наиболее распространенным решением является использование двух карт. Вы можете легко заключить их в класс с дружественным интерфейсом, расширив AbstractMap. ( Обновление: Вот как реализован HashBiMap в Guava: две карты)

Создание новой структуры данных с использованием только массивов и пользовательских классов имеет мало преимуществ. Реализации карты - это легкие обертки структуры данных, которая индексирует ключи. Поскольку вам нужны два индекса, вы также можете использовать две полные карты.

8 голосов
/ 31 мая 2015

Также попробуйте Apache Commons Collections 4 BidiMap Пакет.

6 голосов
/ 20 марта 2012

Google Guava содержит BiMap (двунаправленная карта).

1 голос
/ 25 февраля 2019

На основании этого ответа в этом QA и его комментариях я написал следующее. [Будет проверено]

Двунаправленная карта

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

}
1 голос
/ 22 марта 2016

хорошо для среднего варианта использования, где вам нужен подобный словарь, я не вижу ничего плохого в решении KISS, просто помещая ключ и значение наоборот, сохраняя накладные расходы второй карты или даже библиотеки только для этой цели :

myMap.put("apple", "Apfel");
myMap.put("Apfel", "apple");
0 голосов
/ 31 января 2019

Вы можете определить enum и определить вспомогательный метод для получения ключа.Производительность намного лучше по сравнению с BidiMap.Например,

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;        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...