2012-03-19 9 views
5

Modifica: ha spiegato il problema correttamente ora.Posso avere HashSet come chiave in una HashMap? Suggerisci un'alternativa se non

Ho una mappa di hash dove voglio memorizzare set di parole viste insieme (chiave) e le linee in cui sono state viste insieme (valore). Questa è la struttura mi si avvicinò con:

HashMap<HashSet<String>, HashSet<Integer>> hm= ... 

per gli ingressi:

  1. mango, banana, mela

  2. mela, banana

  3. pesca, Tricheco

  4. tricheco, pesca

Mentre leggo, riga per riga, creo nuove chiavi temporanee (hashset non ancora inserite in hashmap) dalla combinazione di parole nella riga. Ogni chiave temporanea è un hashset di un sottoinsieme delle parole nella riga. Se una chiave temporanea esiste già nel mio hashmap, che posso controllare da

if(hashmap.containsKey(hashset)) 

ho semplicemente aggiungere la nuova linea di corrispondente valore di quella chiave, se non, io faccio una nuova voce nel hashmap e prendersi cura di esso.

In nessun punto si modifica una chiave esistente. Aggiorno solo i loro valori corrispondenti in hasmmap.

mia hashmap, al termine della lettura del file, dovrebbe essere simile a questo

[mela, banana] = [1,2]

[pesca, tricheco] = [3,4]

...

il problema è che il pezzo di codice

if(hashmap.containsKey(hashset)) 

non lo fa alw ays rileva chiavi esistenti. Perchè è questo? Questa struttura non è consentita?

Grazie

+1

Hai provato fuori? – pcalcao

+0

La riga 5 non dovrebbe essere mappata anche a 'peach, walrus'? E che dire del 'mango'? – Thomas

+0

@pcalcao si. si comporta in modo strano a volte rileva l'esistenza del set, a volte no. Voglio solo verificare se HashMap è in grado di gestire hashset con una chiave. – student101

risposta

3

È possibile, ma una volta che è stata aggiunta una HashSet come chiave per un HashMap non è necessario modificare di nuovo, come il HashSet.hashCode() potrebbe cambiare e non sarai mai trovare il vostro HashSet di nuovo. In altre parole, se si sta facendo una cosa del genere, essere sicuri che le chiavi sono immutabili HashSets (vedi anche Matt's answer here)

Un'alternativa è quella di utilizzare il MultiKeyMap insieme a una MultiKey da commons collections

+0

+1 da parte mia, ma perché dovrebbe usare un'alternativa? Poteva semplicemente sostituire l'equivale' e l'hashcode in 'hashset' – Cratylus

+0

@ user384706: L'OP chiedeva un'alternativa possibile –

+0

Ok ma poteva semplicemente estendere' hashset' Non riesco a pensare a un motivo per cui non sarebbe sufficiente – Cratylus

8

Questo dovrebbe funzionare , ma è necessario prestare attenzione alla mutevolezza delle chiavi. Se cambi mai il contenuto di una delle chiavi, il suo hashcode cambierà e la tua mappa inizierà a fare cose strane.Dal javadoc per Map:

Nota: grande cura deve essere esercitata se gli oggetti mutabili sono usati come carta chiavi. Il comportamento di una mappa non viene specificato se il valore di un oggetto viene modificato in modo da influire sui confronti uguali mentre l'oggetto è una chiave nella mappa. Un caso speciale di questo divieto è che non è consentito che una mappa si contenga come chiave. Mentre è consentito per una mappa di contenere se stesso come valore, si consiglia cautela estrema : i metodi equals e hashCode non sono più ben definiti su tale mappa.

per evitare questo, avvolgere i tasti con Collections.unmodifiableSet() immediatamente al momento della creazione, o semplicemente usare ImmutableSet da Guava.

+0

+1 Per aver menzionato la mappa Javadoc –

+0

@matt hi, ho riformulato la domanda ora. Non è stato spiegato molto chiaramente. In nessun momento cambio le chiavi, aggiorno solo i valori a cui punta nella hashmap. – student101

1

Il problema che hai è ben spiegato da @Lukas ans @ Matt.
Penso che potresti scappare utilizzando l'estensione o l'utilizzo di un motivo decoratore per creare uno Hashset che sostituisce equals e hashCode in un modo che è indipendente dal contenuto.

questo modo si può evitare di introdurre dipendenze da vasi di terze parti solo per un problema specifico

+0

Questa è un'opzione interessante! È difficile capire dal testo dell'OP, se produrrà i risultati desiderati, però ... –

+0

Mi stavo chiedendo se c'è qualche trabocchetto che non vedo.IMHO è bene evitare di introdurre librerie aggiuntive se non le usi veramente – Cratylus

Problemi correlati