Problem mit Guavas BiMap und LinkedHashMap
-
12-12-2019 - |
Frage
Ist es in Guave möglich,
Um eine umgekehrte Suche durchzuführen
BiMap
für Schlüssel- und Mehrfachwerte?Genauer gesagt, ich habe einen Schlüssel und entsprechende Mehrfachwerte, ich möchte den Schlüssel von einem Wert erhalten.Zum Speichern mehrerer Werte in
LinkedHashMap
?Genauer gesagt möchte ich mehrere Schlüsselwerte in einer bestimmten Reihenfolge speichern, damit ich die Schlüsselposition in der Liste erhalten kann.
Lösung
Anzeige.1. Ja, es ist möglich, eine umgekehrte Suche mit a durchzuführen BiMap<K, V>
, du rufst einfach an inverse
auf Ihrem BiMap
und du wirst umgekehrt BiMap<V, K>
Sicht von dir BiMap
.
Beispiel (aus der Testsuite von 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"));
}
Anzeige.2. Vorausgesetzt, du meinst „Ich möchte Schlüssel -> mehrere [Sammlungs-]Werte speichern“ (Map<K, Collection<V>>
), ListMultimap
ist wahrscheinlich genau das, was Sie wollen ArrayListMultimap
(behält die Reihenfolge der Werte bei) oder LinkedListMultimap
(behält sowohl die Reihenfolge der Schlüssel als auch der Werte bei).Wenn Ihr Objekt unveränderlich sein soll, empfehle ich Ihnen dringend, es zu verwenden ImmutableListMultimap
.
Sie können auch Ihre eigene Implementierung von erstellen Multimap
durch die Nutzung Fabrik (etwas ausführlich), d.h.Ich benutze:
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. Schauen Sie mal rein Guavas Wiki, was beides erklärt BiMap
Und Multimap
.
Andere Tipps
Der nächstgelegene in Guava ist Multiset
um mehrere Werte dem Schlüssel zuzuordnen, aber ich bezweifle, dass dies Ihren Anforderungen entspricht.
- Ich bezweifle, dass es eine gute Idee ist, Schlüssel mithilfe von Werten zu suchen (wenn Sie mehrere Werte einem einzelnen Schlüssel zugeordnet haben). Um dies zu tun, sollte Ihr Wert eindeutig sein und Ihre Datenstruktur berücksichtigen (was so ist).
Map<Key, Collection<Value>
) Es kann nicht garantiert werden, dass es eindeutige Werte hat. - Die andere Option mit Guave ist
BiMap
Dies erfordert eindeutige Werte und kann umgekehrte Zuordnungen (Wert -> Schlüssel) bereitstellen. Da Sie jedoch mehrere Werte demselben Schlüssel zuordnen müssen, ist dies ebenfalls keine gute Lösung.
Als @Xaerxess sagt in seine Antwort Zu Ihrer zweiten Frage können Sie Ihre eigene stellen ListMultimap
das verwendet a LinkedHashMap
als Hintergrundkarte unter Verwendung der Multimaps.newListMultimap
Methode.
Für Ihre erste Frage, bei der Schlüssel mehreren Werten zugeordnet sind (z. B.A Multimap
), können Sie die Methode verwenden Multimaps.invertFrom
um eine invertierte Kopie Ihres Originals zu erstellen Multimap
um inverse Suchvorgänge durchzuführen.Sie können auch eine erstellen ImmutableListMultimap
Kopie des Originals und verwenden Sie es inverse()
Methode, um das Gegenteil zu erhalten, obwohl dabei einfach das Original kopiert wird Multimaps.invertFrom
tut es (obwohl es es zwischenspeichert, sodass wiederholte Aufrufe von inverse()
das gleiche Exemplar zurücksenden.)
Dies lohnt sich wahrscheinlich, wenn Ihnen der zusätzliche Speicherverbrauch nichts ausmacht, Sie mehrere inverse Suchvorgänge durchführen möchten und die inverse Kopie nicht benötigen, um über Änderungen am Original, die nach der Erstellung vorgenommen werden, auf dem Laufenden zu bleiben .Wenn Sie nur die Schlüssel suchen möchten, die einem bestimmten Wert zugeordnet sind, können Sie dies in einer Iteration der Einträge tun, ohne eine vollständige Kopie zu erstellen.