Sto cercando un modo per memorizzare coppie chiave-valore. Ho bisogno che la ricerca sia bidirezionale, ma allo stesso tempo ho bisogno di memorizzare più valori per la stessa chiave. In altre parole, qualcosa come una BidiMap, ma per ogni chiave ci possono essere più valori. Ad esempio, deve essere in grado di contenere coppie come: "s1" -> 1, "s2" -> 1, "s3" -> 2, e ho bisogno di essere in grado di ottenere il valore mappato a ciascuna chiave, e per ogni valore, prendi tutte le chiavi ad esso associate.Mappa multivalore bidirezionale in Java
risposta
Quindi hai bisogno di supporto per le relazioni molti-a-molti? Il minimo che si possa ottenere èMultimap
come ha scritto @Mechkov - ma in particolare la combinazione Multimap
con Multimaps.invertFrom
. "BiMultimap" non è ancora implementato, ma c'è an issue che richiede questa funzione nella libreria Google Guava.
A questo punto si hanno poche opzioni:
Se il "BiMultimap" sta per costante immutabile - utilizzare
Multimaps.invertFrom
eImmutableMultimap
/ImmutableListMultimap
/ImmutableSetMultimap
(ciascuno dei theese tre ha diversi valori di raccolta memorizzazione). Alcuni di codice (esempio tratto dalla app io sviluppo, utilizzaEnum
s eSets.immutableEnumSet
):public class RolesAndServicesMapping { private static final ImmutableMultimap<Service, Authority> SERVICES_TO_ROLES_MAPPING = ImmutableMultimap.<Service, Authority>builder() .put(Service.SFP1, Authority.ROLE_PREMIUM) .put(Service.SFP, Authority.ROLE_PREMIUM) .put(Service.SFE, Authority.ROLE_EXTRA) .put(Service.SF, Authority.ROLE_STANDARD) .put(Service.SK, Authority.ROLE_STANDARD) .put(Service.SFP1, Authority.ROLE_ADMIN) .put(Service.ADMIN, Authority.ROLE_ADMIN) .put(Service.NONE, Authority.ROLE_DENY) .build(); // Whole magic is here: private static final ImmutableMultimap<Authority, Service> ROLES_TO_SERVICES_MAPPING = SERVICES_TO_ROLES_MAPPING.inverse(); // before guava-11.0 it was: ImmutableMultimap.copyOf(Multimaps.invertFrom(SERVICES_TO_ROLES_MAPPING, HashMultimap.<Authority, Service>create())); public static ImmutableSet<Authority> getRoles(final Service service) { return Sets.immutableEnumSet(SERVICES_TO_ROLES_MAPPING.get(service)); } public static ImmutableSet<Service> getServices(final Authority role) { return Sets.immutableEnumSet(ROLES_TO_SERVICES_MAPPING.get(role)); } }
Se si vuole veramente il tuo Multimap per essere modificabili, sarà difficile mantenere sia K-> V e V-> Varianti K a meno che non si modifichi solo
kToVMultimap
e si chiamiinvertFrom
ogni volta che si desidera avere la copia invertita (e tale copia non è modificabile per garantire che non si modifichi accidentalmentecosa non si aggiornakToVMultimap
). Questo non è ottimale, ma dovrebbe essere fatto in questo caso.(Non è il caso, probabilmente, citato come bonus):
BiMap
l'interfaccia e le classi che implementano ha.inverse()
metodo che dàBiMap<V, K>
vista daBiMap<K, V>
e se stesso dopobiMap.inverse().inverse()
. Se this issue ho menzionato prima, probabilmente avrà qualcosa di simile.(EDIT ottobre 2016) È inoltre possibile utilizzare new graph API che sarà presente in Guava 20:
Nel suo complesso, comune.grafico supporta grafici delle seguenti varietà:
- grafi orientati
- grafi non orientati
- nodi e/o bordi con i valori associati (pesi, etichette, ecc)
- grafici che fanno/non fare consentire self-loop
- grafici che fanno/non consentono bordi paralleli (grafici con bordi paralleli vengono talvolta chiamati multigrafi)
- grafici i cui nodi/bordi sono inserimento ordinato, ordinato o non ordinato 0.123.
Speranza I got you giusti
class A {
long id;
List<B> bs;
}
class B {
long id;
List<A> as;
}
Cosa c'è di sbagliato con avere due mappe, KEY-> valori, chiavi VALORI>?
Ho pensato che tenere due copie degli stessi dati sarebbe più soggetto a errori. Comunque, dopo tutte le collezioni che ho visto, sto iniziando a pensare che sia la soluzione migliore. –
Basta creare un wrapper per le mappe che li mantiene sincronizzati. – Stefan
Non mi piace l'approccio approvato da questa risposta. Ci sono molte cose potenzialmente sbagliate in questo, tra cui forse reinventare la ruota, scrivere i propri bug lungo il percorso, sicurezza dei thread, ecc. – bacar
L'implementazione di Google Guava MultiMap è ciò che sto utilizzando per questi scopi.
Map<Key Collection<Values>>
dove Collection può essere un ArrayList ad esempio. Consente a più valori memorizzati in una raccolta di essere mappati su una chiave. Spero che questo aiuti!
Non bidirezionale. – Stefan
spero utilizzando MultivaluedMap risolve il problema. Si prega di trovare la documentazione da oracolo sotto il collegamento.
http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/MultivaluedMap.html
Questa è un'interfaccia. Ci sono delle implementazioni? – amoebe
Utilizzo di Google Guava possiamo scrivere un BiMulitMap primitivo come di seguito.
import java.util.Collection;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
public class BiMultiMap<K,V> {
Multimap<K, V> keyToValue = ArrayListMultimap.create();
Multimap<V, K> valueToKey = ArrayListMultimap.create();
public void putForce(K key, V value) {
keyToValue.put(key, value);
valueToKey.put(value, key);
}
public void put(K key, V value) {
Collection<V> oldValue = keyToValue.get(key);
if (oldValue.contains(value) == false) {
keyToValue.put(key, value);
valueToKey.put(value, key);
}
}
public Collection<V> getValue(K key) {
return keyToValue.get(key);
}
public Collection<K> getKey(V value) {
return valueToKey.get(value);
}
@Override
public String toString() {
return "BiMultiMap [keyToValue=" + keyToValue + ", valueToKey=" + valueToKey + "]";
}
}
Spero che questo aiuti alcune esigenze di base della Multi mappa bidirezionale. Nota che K e V devono implementare correttamente il metodo hascode e uguali
- 1. Mappa bidirezionale in Java?
- 2. Mappa bidirezionale
- 3. Mappa bidirezionale in .NET
- 4. Mappa bidirezionale in cacao
- 5. Una mappa bidirezionale in clojure?
- 6. Libreria di crittografia bidirezionale Java
- 7. Parametri multivalore opzionali in SSRS
- 8. Java: ricerca bidirezionale many-to-one
- 9. Bind ToggleGroup bidirezionale in JavaFX
- 10. Raggruppamento degli attributi multivalore in SOLR
- 11. È possibile aggiungere attributi multivalore in DynamoDB?
- 12. Composizione funzionale con funzioni multivalore in haskell?
- 13. Ordinamento con campo multivalore in Solr
- 14. mappa Groovy e mappa Java su generici
- 15. Punteggio del campo multivalore solr
- 16. Campi multivalore una buona idea?
- 17. JCR SQL2 Ricerca proprietà multivalore
- 18. dizionario bidirezionale?
- 19. Chiave Java - mappa chiave
- 20. Rubrica indirizzi url multivalore iphone
- 21. Tabella hash bidirezionale in Erlang
- 22. bidirezionale associazione dati in ASP.NET
- 23. Associazione dati bidirezionale in backbone.js
- 24. copia dei riferimenti una mappa in Java
- 25. Convertire la mappa Java in Javascript Map
- 26. Pretty-print una mappa in Java
- 27. SSL bidirezionale per servizi Web su GAE (java)
- 28. Come utilizzare JPL (interfaccia bidirezionale Java/Prolog) su Windows?
- 29. Java mettendo impostato sulla mappa
- 30. Java 8: espressioni lambda Mappa
Si parla della necessità di avere più valori per chiave, ma nell'esempio non si ha alcuna chiave con più valori, ma un valore con due chiavi. Probabilmente dovresti chiarirlo. Se il tuo esempio si adatta alla tua domanda otterrai risposte migliori ;-) – pushy
http://www.jguru.com/faq/view.jsp?EID=1317828 qui puoi trovare come creare multimap – maks
@pushy, stesso problema, se inverto la mappa e mantengo gli interi come chiavi anziché come valori, ottengo una mappatura uno-a-molti. Comunque, grazie per la correzione. :) –