Двустороннее сопоставление с использованием единой структуры данных

Недавно на работе я столкнулся с некоторым кодом (воссозданным, чтобы он был похож на то, с чем я имею дело), ​​похожим на код ниже.

Есть ли способ переработать приведенный ниже код, чтобы использовать одну структуру данных (с учетом производительности)?

Вот некоторый код, чтобы проиллюстрировать, что я имею в виду:

public class ObjectMapper {

    private Map<UUID,Integer> uuidMap;
    private Map<Integer,UUID> indexMap;

    public ObjectMapper(){
        uuidMap = new HashMap<UUID,Integer>();
        indexMap = new HashMap<Integer,UUID>();
    }

    public void addMapping(int index, UUID uuid){
        uuidMap.put(uuid, index);
        indexMap.put(index, uuid);
    }


    .
    .
    .

    public Integer getIndexByUUID(UUID uuid){
        return uuidMap.get(uuid);
    }

    public UUID getUUIDByIndex(Integer index){
        return indexMap.get(index);
    }


}

person mainstringargs    schedule 13.05.2009    source источник
comment
Существующий подход использования экземпляра карты для каждого сопоставления кажется мне разумным.   -  person Steve Kuo    schedule 14.05.2009


Ответы (4)


На это отвечает здесь с рекомендацией использовать BiMap из Коллекции Google

person Yishai    schedule 13.05.2009
comment
Прохладно. Однако я действительно надеялся найти способ сделать это без использования внешнего Jar. Но это может быть невозможно. - person mainstringargs; 14.05.2009
comment
Если вы посмотрите на код BiMap, они используют двойную карту для его реализации, поэтому я бы сказал, что в любом случае это наиболее очевидная реализация. google-collections.googlecode.com/ svn/trunk/src/com/google/ - person Yishai; 14.05.2009

Коллекции Apache поддерживают интерфейс BidiMap. и множество достаточно эффективных реализаций.

person Uri    schedule 13.05.2009

Вы можете использовать один Map<Object,Object> для обоих сопоставлений. Некрасиво, конечно. Производительность должна быть примерно такой же или немного лучше в том маловероятном случае, если у вас много ObjectMapper с несколькими отображаемыми значениями.

person Tom Hawtin - tackline    schedule 13.05.2009

Вы можете использовать BiMap из Коллекции Eclipse.

BiMap — это карта, которая позволяет пользователям выполнять поиск в обоих направлениях. И ключи, и значения в BiMap уникальны.

Основная реализация HashBiMap.

inverse()

BiMap.inverse() возвращает представление, в котором позиции типа ключа и типа значения поменяны местами.

MutableBiMap<Integer, String> biMap =
  HashBiMap.newWithKeysValues(1, "1", 2, "2", 3, "3");
MutableBiMap<String, Integer> inverse = biMap.inverse();
Assert.assertEquals("1", biMap.get(1));
Assert.assertEquals(1, inverse.get("1"));
Assert.assertTrue(inverse.containsKey("3"));
Assert.assertEquals(2, inverse.put("2", 4));

put()

MutableBiMap.put() ведет себя как Map.put() на обычной карте, за исключением того, что при добавлении повторяющегося значения возникает ошибка.

MutableBiMap<Integer, String> biMap = HashBiMap.newMap();
biMap.put(1, "1"); // behaves like a regular put()
biMap.put(1, "1"); // no effect
biMap.put(2, "1"); // throws IllegalArgumentException

forcePut()

Это ведет себя как MutableBiMap.put(), но автоматически удаляет запись карты с тем же значением, прежде чем поместить пару ключ-значение в карту.

MutableBiMap<Integer, String> biMap = HashBiMap.newMap();
biMap.forcePut(1, "1"); // behaves like a regular put()
biMap.forcePut(1, "1"); // no effect
biMap.forcePut(1, "2"); // replaces the [1,"1"] pair with [1, "2"]
biMap.put(2, "2"); // removes the [1, "2"] pair before putting
Assert.assertFalse(biMap.containsKey(1));
Assert.assertEquals(HashBiMap.newWithKeysValues(2, "1"), biMap);

Примечание. Я коммиттер коллекций Eclipse.

person Craig P. Motlin    schedule 21.12.2013