Проблема с BiMap и LinkedHashMap в Guava
Это возможно в Гуаве,
Провести обратный поиск в
BiMap
для ключа и нескольких значений? Точно, у меня есть ключ и соответствующие несколько значений, я хочу получить ключ от значения.Для хранения нескольких значений в
LinkedHashMap
? Точно, я хочу хранить, ключ - несколько значений в некотором порядке, таким образом я могу получить ключевую позицию в списке.
3 ответа
Объявление. 1. Да, можно сделать обратный поиск с BiMap<K, V>
звоните inverse
на ваше BiMap
и вы перевернетесь BiMap<V, K>
вид вашего BiMap
,
Пример (взят из набора тестов Guava):
public void testMapConstructor() {
/* Test with non-empty Map. */
Map<String, String> map = ImmutableMap.of(
"canada", "dollar",
"chile", "peso",
"switzerland", "franc");
HashBiMap<String, String> bimap = HashBiMap.create(map);
assertEquals("dollar", bimap.get("canada"));
assertEquals("canada", bimap.inverse().get("dollar"));
}
Объявление. 2. Предполагая, что вы имеете в виду "Я хочу сохранить, ключ -> несколько [коллекция] значений" (Map<K, Collection<V>>
), ListMultimap
это, вероятно, то, что вы хотите, более точно ArrayListMultimap
(сохраняет порядок значений) или LinkedListMultimap
(сохраняет порядок ключей и значений). Если ваш объект будет неизменным, я настоятельно советую вам использовать ImmutableListMultimap
,
Вы также можете создать свою собственную реализацию Multimap
используя фабрику (немного многословно), то есть я использую:
private static <K, V> ListMultimap<K, V> makeLinkedArrayListMultimap() {
return Multimaps.newListMultimap(Maps.<K, Collection<V>>newLinkedHashMap(),
new Supplier<List<V>>() {
@Override public List<V> get() {
return Lists.newArrayList();
}
});
}
public static void main(final String[] args) {
final ListMultimap<String, String> multimap = makeLinkedArrayListMultimap();
multimap.putAll("one", ImmutableList.of("zero", "three"));
multimap.putAll("two", ImmutableList.of("three", "four", "three"));
multimap.putAll("three", ImmutableList.<String>of()); // note that this doesn't add key to multimap
multimap.put("four", "forty-two");
System.out.println(multimap);
// prints {one=[one, three], two=[three, four, three], four=[forty-two]}
final List<String> listForOnes = multimap.get("one");
System.out.println(listForOnes.get(0));
// prints zero
}
PS Взгляните на вики Guava, которая объясняет оба BiMap
а также Multimap
,
Ближайший в Гуаве Multiset
сопоставить несколько значений с ключом, но я сомневаюсь, что он удовлетворяет вашим требованиям.
- Я сомневаюсь, что это хорошая идея, чтобы искать ключ, используя значения (если у вас есть несколько значений, сопоставленных с одним ключом), чтобы сделать это, ваше значение должно быть уникальным и с учетом вашей структуры данных (которая похожа на
Map<Key, Collection<Value>
) нельзя гарантировать уникальные значения. - Другой вариант с гуавой
BiMap
который требует уникальных значений и может обеспечить обратное сопоставление (значение -> ключ), но, поскольку вам необходимо сопоставить несколько значений с одним и тем же ключом, это также не очень подходит.
Как Xaerxess говорит в своем ответе на ваш второй вопрос, вы можете сделать свой собственный ListMultimap
который использует LinkedHashMap
в качестве вспомогательной карты с использованием Multimaps.newListMultimap
метод.
Для вашего первого вопроса, где у вас есть ключи, сопоставленные с несколькими значениями (т.е. Multimap
), вы можете использовать метод Multimaps.invertFrom
создать перевернутую копию вашего оригинала Multimap
сделать обратный поиск. Также вы можете создать ImmutableListMultimap
копия оригинала и использовать его inverse()
метод, чтобы получить обратное, хотя это просто скопировать оригинал, как Multimaps.invertFrom
делает (хотя это будет кешировать это так многократные вызовы inverse()
вернуть ту же копию.)
Это, вероятно, того стоит, если вы не возражаете против дополнительного потребления памяти, хотите выполнить несколько обратных поисков и не нуждаетесь в обратной копии, чтобы оставаться в курсе изменений оригинала, которые происходят после его создания., Если вы просто хотите найти ключи, которые соответствуют одному конкретному значению, вы можете сделать это за одну итерацию записей без создания полной копии.