2015-05-13 18 views
9

Voglio memorizzare un valore basato su un tasto, composto da un insieme di elementi. Qualcosa come l'esempio qui sotto. Naturalmente so che il mio pseudo-esempio non funzionerebbe, poichè l'hash dell'oggetto sarà probabilmente il suo indirizzo che sarà unico per ogni nuova istanza, indipendentemente dal suo contenuto.Come utilizzare set di elementi come chiave nelle mappe java?

// in this pseudo-example this is my SET http://algs4.cs.princeton.edu/35applications/SET.java.html 
    // but the idea is that values are unique 
    HashMap<SET<Integer>, String> map = new HashMap<>(); 
    SET a = new SET(); 
    a.add(1); 
    a.add(2); 
    a.add(5); 

    SET b = new SET(); 
    b.add(5); 
    b.add(1); 
    b.add(2); 

    map.put(a, "w00t"); 

    System.out.println(map.get(b)); // I would want to get "w00t" because my key is the same set of elements 

Certo che posso solo ordinare e concatenare i valori impostati come una stringa, con un separatore e l'uso che in una struttura HashMap<String, String> ma che semplicemente non si sente bene. Sono abbastanza nuovo alla programmazione Java quindi potrebbe esserci una soluzione ovvia che mi manca.

+0

Devi cercare in 'keySet()'. Inoltre è un 'Set' e non' SET' –

+0

Penso che ci sia un grosso problema qui se si desidera utilizzare le raccolte per questo lavoro. Sono tutti mutabili. Cosa succede se aggiungi set (2,3) e (1,2,3), ma poi decidi di rimuovere un {1} dal secondo set? Meglio creare un oggetto immutabile separato per questo, altrimenti sarà preoccupante. – pnadczuk

+0

Mi rendo conto di questo, ma nel mio caso non modificherò gli oggetti una volta memorizzati. Idealmente mi piacerebbe avere un oggetto immutabile che inizializzo da altro iterabile, ma non ce n'è uno che riesco a trovare :( – ddinchev

risposta

7

Se si utilizza al posto del tuo set personalizzato (sto supponendo che è una classe personalizzata), che avrebbe funzionato bene, dal momento che HashSet override hashCode e equals (per l'esattezza, HashSet estende AbstractSet che ignora questi metodi), quindi può fungere da chiave in un HashMap.

Tuttavia, se si modifica un Set che funge da chiave nella Mappa, non sarà possibile individuare quella chiave nella Mappa in un secondo momento. Questo è il rischio che si incontra quando si usano oggetti mutabili come chiavi in ​​una HashMap.

HashMap<HashSet<Integer>, String> map = new HashMap<HashSet<Integer>, String>(); 
HashSet<Integer> a = new HashSet<Integer>(); 
a.add(1); 
a.add(2); 
a.add(5); 

HashSet<Integer> b = new HashSet<Integer>(); 
b.add(5); 
b.add(1); 
b.add(2); 

map.put(a, "w00t"); 

System.out.println(map.get(b)); 

Queste uscite w00t.

+0

L'ho esaminato Non va in override, ma eredita. – ddinchev

+1

@ddinchev Funziona bene Provalo e vedi di persona – gdejohn

+2

@ddinchev Sì, sono stato impreciso, AbstractSet esegue l'override – Eran

0

Creare una classe di raccolta e sovrascrivere hashcode() in un modo in cui viene restituito lo stesso hashcode per diverse istanze di raccolta con lo stesso contenuto. Puoi semplicemente sovrascrivere il metodo in una classe derivante dalla raccolta desiderata. Devi reimplementare uguali (oggetto o) pure.

+0

Le implementazioni di set JDK lo fanno già per te. – gdejohn

+0

Che ne dici di due istanze OrderedSet con un comparatore diverso? – Traubenfuchs

+0

Funziona ancora. Se controlli i documenti per ['TreeSet'] (https://docs.oracle.com/javase/8/docs/api/java/util/TreeSet.html), puoi vedere che eredita il suo [' equals () '] (https://docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#equals-java.lang.Object-) e [' hashCode() '] (https: //docs.oracle.com/javase/8/docs/api/java/util/AbstractSet.html#hashCode--) implementazioni da 'AbstractSet'. "L'interfaccia Set pone ulteriori clausole, oltre a quelle ereditate dall'interfaccia Collection, sui contratti di tutti i costruttori e sui contratti dei metodi add, equal e hashCode." – gdejohn

-2

Non è stato aggiunto il set b alla mappa. Per prima cosa aggiungi entrambi i set e poi prova ad ottenere il valore associato al tasto b.

+2

Questo è il punto dell'OP: entrambi i set hanno gli stessi elementi e dovrebbero essere identici, ma un oggetto aggiunto con 'a' poiché la chiave non può essere recuperata usando' b'. Ciò accade perché non ha eseguito l'override di 'hashCode' o' equals' nella sua implementazione del set personalizzato. –

-1

Dipende dall'implementazione della classe SET. È possibile estendere la classe java.util.HashSet o implementare i metodi equals() e hashCode() nella classe SET. Qualsiasi soluzione funzionerà.

Problemi correlati