Двустороннее сопоставление с использованием единой структуры данных
Вопрос
Недавно я наткнулся на некоторый код на работе (воссозданный, чтобы быть похожим на то, с чем я имею дело), похожий на код ниже.
Есть ли способ переработать приведенный ниже код, чтобы использовать одну структуру данных (с учетом производительности)?
Вот код, иллюстрирующий то, что я имею в виду:
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);
}
}
Решение
Это ответ здесь с рекомендацией использовать BiMap от Коллекции Google
Другие советы
Коллекции Apache поддерживают БидиКарта интерфейс и множество довольно эффективных реализаций.
Вы можете использовать один Map<Object,Object>
сделать оба сопоставления.Некрасиво, конечно.Производительность должна быть примерно такой же или немного лучше в том маловероятном случае, если у вас много ObjectMapper
s с несколькими сопоставленными значениями.
Вы можете использовать БиМап от Коллекции затмений.
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.