Domanda

Ho due tipi di oggetti nella mia applicazione in cui ogni oggetto di un tipo ha esattamente un oggetto corrispondente dell'altro tipo.

La scelta ovvia per tenere traccia di questa relazione è un Map<type1, type2>, come una HashMap. Ma in qualche modo, sono sospettoso. Posso usare un oggetto come chiave nella Mappa, passarlo in giro, farlo sedere anche in un'altra raccolta e recuperare il suo partner dalla Mappa in qualsiasi momento?

Dopo aver creato un oggetto, tutto ciò che sto passando è un identificatore, giusto? Quindi probabilmente nessun problema lì. Cosa succede se serializzo e deserializzo la chiave?

Qualche altro avvertimento? Dovrei usare qualcos'altro per correlare le coppie di oggetti, come un numero che mi genera?

È stato utile?

Soluzione

  1. La chiave deve implementare .equals() e .hashCode() correttamente
  2. La chiave non deve essere modificata in alcun modo che cambi il suo valore HashMap mentre è usata come chiave
  3. Idealmente, qualsiasi oggetto utilizzato come chiave in <=> dovrebbe essere immutabile. Ciò garantirebbe automaticamente che 2. sia sempre ritenuto vero.
  4. Gli oggetti che altrimenti potrebbero essere GCed potrebbero essere mantenuti in giro quando vengono utilizzati come chiave e / o valore.

Altri suggerimenti

  

Ho due tipi di oggetti nel mio   applicazione in cui ogni oggetto di uno   kind ha esattamente un corrispondente   oggetto dell'altro tipo.

Sembra davvero una relazione has-a e quindi potrebbe essere implementata usando un semplice attributo.

Dipende dall'implementazione della mappa scelta:

  • HashMap utilizza equals () e hashCode () . Per impostazione predefinita (in Oggetto) questi sono basati sull'identità dell'oggetto, che funzionerà correttamente a meno che non si serializzi / deserializzi. Con una corretta implementazione di equals () e hashCode () in base al contenuto dell'oggetto non avrai problemi, purché non lo modifichi mentre è una chiave in una mappa hash.

  • TreeMap utilizza compareTo () . Non esiste un'implementazione predefinita, quindi è necessario fornirne una. Le stesse limitazioni si applicano all'implementazione di hashCode () e equals () sopra.

Puoi usare una mappa standard, ma così facendo manterrai forti riferimenti ai tuoi oggetti nella mappa. Se i tuoi oggetti sono referenziati in un'altra struttura e hai bisogno della Mappa solo per collegarli insieme, considera l'utilizzo di una WeakHashMap.

E BTW non devi sovrascrivere equals e hashCode a meno che tu non debba considerare diverse istanze di un oggetto come uguali ...

  

Posso usare un oggetto come chiave nella Mappa, passarlo in giro, farlo sedere anche in un'altra raccolta e recuperare il suo partner dalla Mappa in qualsiasi momento?

Sì, nessun problema qui.

  

Dopo aver creato un oggetto, tutto ciò che sto passando è un identificatore, giusto? Quindi probabilmente nessun problema lì. Cosa succede se serializzo e deserializzo la chiave?

Esatto, stai solo passando un riferimento - indicheranno tutti lo stesso oggetto reale. Se serializzi o deserializzi l'oggetto, ciò creerebbe un nuovo oggetto. Tuttavia, se il tuo oggetto implementa equals e hashCode correttamente, dovresti comunque essere in grado di utilizzare il nuovo oggetto deserializzato per recuperare elementi dalla mappa.

  

Qualche altro avvertimento? Dovrei usare qualcos'altro per correlare le coppie di oggetti, come un numero che mi genera?

Per quanto riguarda Caveat, sì, non è possibile modificare nulla che provocherebbe la modifica dell'hashCode dell'oggetto mentre l'oggetto si trova nella Mappa.

Qualsiasi oggetto può essere una chiave della mappa. La cosa importante qui è assicurarsi di sovrascrivere .equals () e .hashCode () per tutti gli oggetti che verranno usati come chiavi della mappa.

La ragione per cui lo fai è che se non lo fai, uguali saranno intesi come uguaglianza di oggetti, e l'unico modo in cui sarai in grado di trovare " uguale " le chiavi della mappa devono avere un handle per l'oggetto originale stesso.

Sostituisci l'hashcode perché deve essere coerente con uguale a. Questo è così che gli oggetti che hai definito uguale a hash sono identici.

I punti di errore sono l'hashcode e le funzioni uguali. Se non producono valori di ritorno coerenti e corretti, la Mappa si comporterà in modo strano. Java efficace ha un'intera sezione su di essi ed è altamente, altamente raccomandato.

Potresti prendere in considerazione di Google Collection BiMap .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top