Problema com Goiaba do BiMap e LinkedHashMap
-
12-12-2019 - |
Pergunta
É possível Goiaba,
Para realizar uma pesquisa inversa em
BiMap
para a chave e vários valores?Precisamente, eu tenho a chave e correspondente de vários valores, eu quero pegar a chave de um valor.Para armazenar vários valores em
LinkedHashMap
?Precisamente, eu quero store, chave de vários valores em uma certa ordem, assim, eu possa obter a chave de posição na lista.
Solução
Um anúncio.1. Sim, é possível fazer uma pesquisa inversa com um BiMap<K, V>
, você acabou de chamar inverse
no seu BiMap
e você começa inversa BiMap<V, K>
visualizar do seu BiMap
.
Exemplo (retirado de Goiaba do conjunto de teste):
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"));
}
Um anúncio.2. Supondo que você quer dizer "Eu quero store, chave -> vários [colecção] e valores" (Map<K, Collection<V>>
), ListMultimap
é provavelmente o que você quiser, mais precisamente ArrayListMultimap
(preserva valores de ordem) ou LinkedListMultimap
(preserva ambas as chaves e valores de ordem).Se o objeto for vai ser imutável, eu aconselho fortemente que você use ImmutableListMultimap
.
Você também pode criar sua própria implementação de Multimap
usando fábrica (pouco extenso), i.é.Eu uso:
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
}
P. S. Dê uma olhada no Goiaba do wiki, que explica ambos os BiMap
e Multimap
.
Outras dicas
O mais próximo, em Goiaba é Multiset
para mapear vários valores para a chave, mas eu duvido que ele satisfaz a sua exigência.
- Eu duvido que é uma boa idéia para procurar a chave usando valores (quando você tiver vários valores mapeados para chave única), para fazer isso o seu valor deve ser único e considerando a estrutura de dados (que é como
Map<Key, Collection<Value>
) não pode ser garantido para ter valores únicos. - A outra opção com goiaba é
BiMap
o que requer valores exclusivos e pode fornecer uma inversa (mapeamentos de valor -> chave), mas desde que você precisa para mapear vários valores para a mesma chave, esta também não é uma boa opção.
Como @Xaerxess diz em sua resposta para sua 2ª pergunta, você pode fazer o seu próprio ListMultimap
que usa um LinkedHashMap
como o seu apoio mapa usando o Multimaps.newListMultimap
o método.
Para a sua 1ª pergunta, onde você tem as chaves mapeado para múltiplos valores (por exemplo,um Multimap
), você pode usar o método Multimaps.invertFrom
para criar uma cópia invertida do original Multimap
para fazer o inverso pesquisas sobre.Além disso, você pode criar uma ImmutableListMultimap
cópia do original e usa a sua inverse()
método para obter o inverso, no entanto, que apenas vai copiar o original apenas como Multimaps.invertFrom
faz (apesar de cache para chamadas repetidas para inverse()
retornar a mesma cópia.)
Esta é provável que vale a pena se você não mente a extra consumo de memória, vai querer fazer várias inverso pesquisas, e não precisa o inverso copiar para manter-se atualizado com as alterações ao original que acontecem depois de o criar.Se você quiser apenas para pesquisa as teclas mapeadas para um valor específico, você pode fazer isso em uma iteração das entradas, sem criar uma cópia completa.