Двустороннее сопоставление с использованием единой структуры данных - PullRequest
4 голосов
/ 14 мая 2009

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

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

Вот код для иллюстрации того, что я имею в виду:

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


}

Ответы [ 4 ]

5 голосов
/ 14 мая 2009

Ответ здесь с рекомендацией использовать BiMap из Google Collections

2 голосов
/ 14 мая 2009

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

1 голос
/ 21 декабря 2013

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

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.

1 голос
/ 14 мая 2009

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

...