Problema con BiMap e LinkedHashMap di Guava
-
12-12-2019 - |
Domanda
È possibile a Guava,
Per condurre una ricerca inversa in
BiMap
per valori chiave e multipli?Precisamente, ho una chiave e valori multipli corrispondenti, voglio ottenere la chiave da un valore.Per memorizzare più valori in
LinkedHashMap
?Precisamente, voglio memorizzare, chiave - più valori in un certo ordine, così posso ottenere la posizione chiave nell'elenco.
Soluzione
Anno Domini.1. Sì, è possibile eseguire una ricerca inversa con a BiMap<K, V>
, devi solo chiamare inverse
sul tuo BiMap
e ti invertisci BiMap<V, K>
visualizzazione del tuo BiMap
.
Esempio (tratto dalla suite di test di 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"));
}
Anno Domini.2. Supponendo che tu intenda "Voglio archiviare chiave -> più valori [raccolta]" (Map<K, Collection<V>>
), ListMultimap
è probabilmente quello che vuoi, più precisamente ArrayListMultimap
(preserva l'ordine dei valori) o LinkedListMultimap
(preserva sia l'ordine delle chiavi che dei valori).Se il tuo oggetto sarà immutabile, ti consiglio vivamente di usarlo ImmutableListMultimap
.
Puoi anche creare la tua implementazione di Multimap
usando fabbrica (un po' prolisso), cioèIo 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
}
PS Dare un'occhiata a Wiki di Guava, il che spiega entrambi BiMap
E Multimap
.
Altri suggerimenti
Il più vicino a Guava è Multiset
per mappare più valori per il tasto, ma dubito che soddisfi il tuo requisito.
- .
- dubito che sia una buona idea cercare la chiave usando i valori (quando si dispone di più valori mappati su chiave singola), al fine di fare questo il tuo valore dovrebbe essere unico e considerando la struttura dei dati (che è come
Map<Key, Collection<Value>
) Non puòessere garantito per avere valori unici.
- L'altra opzione con Guava è
BiMap
che richiede valori unici e può fornire un tasto di mappature inverse (valore ->) ma dal momento che è necessario mappare più valori allo stesso tasto, anche questa non è una buona vestibilità.
come @xaerxess dice in La sua risposta alla tua seconda domanda, puoi creare il tuo ListMultimap
che utilizza un LinkedHashMap
come mappa di supporto utilizzando il metodo Multimaps.newListMultimap
.
Per la prima domanda, in cui hai le chiavi mappate su più valori (ad esempio un Multimap
), è possibile utilizzare il metodo Multimaps.invertFrom
per creare una copia invertita del tuo Multimap
originale per fare ricerche inverse su. Inoltre, è possibile creare una copia ImmutableListMultimap
dell'originale e utilizzare il suo metodo inverse()
per ottenere l'inverso, sebbene sia solo per copiare l'originale proprio come Multimaps.invertFrom
fa (anche se la cache lo ripeterà così ripetutamente a inverse()
restituisce la stessa copia.)
Probabilmente ne vale la pena se non ti dispiace il consumo di memoria extra, vorrà fare più ricerche inverse e non hanno bisogno della copia inversa per rimanere aggiornati con modifiche all'originale che accadono dopo Lo crei. Se vuoi semplicemente cercare le chiavi che mappano a un valore specifico, puoi farlo in un'unica iterazione delle voci senza creare una copia completa.