2009-12-24 10 views

risposta

7

Java non genera hashCode(), ad esempio non accade nulla di automatico. Tuttavia, Object genera un codice hash basato sull'indirizzo di memoria dell'istanza dell'oggetto. La maggior parte delle classi (specialmente se la si utilizzerà in una qualsiasi delle API Collection) dovrebbe implementare il proprio HashCode (e contrattualizzare il proprio metodo di equals).

+0

Dal file Object.java '(Questo è tipicamente ** ** attuato convertendo l'indirizzo ** ** interna dell'oggetto in numero intero, ma questa implementazione la tecnica è ** non ** richiesta dal linguaggio di programmazione Java TM.) - Sottolineo la mia. –

+0

Questo hashCode restituirà un valore diverso dopo che l'oggetto viene spostato quando si verifica GC? – Jacky

+2

L'idea che hashCode usi l'indirizzo di memoria è un artefatto storico http://stackoverflow.com/questions/36236615/does-object-tostring-or-object-hashcode-ever-give-the-memory-address-of-the -obje – Raedwald

23

Il di Object è in realtà un metodo nativo e l'implementazione non è in realtà pura Java. Ora, per quanto riguarda il come funziona, this answer from Tom Hawtin fa un grande lavoro a spiegarla:

Molte persone sostengono che Object.hashCode restituirà l'indirizzo della rappresentazione oggetto in memoria. Nelle implementazioni moderne gli oggetti si spostano effettivamente all'interno della memoria. Invece, viene utilizzata un'area dell'intestazione dell'oggetto per memorizzare il valore, che può essere derivato pigramente dall'indirizzo di memoria nel momento in cui il valore viene richiesto per la prima volta.

L'intera risposta vale davvero la lettura.

5

In base alla documentazione dell'API della piattaforma Java, il calcolo dell'hashcode si basa sull'indirizzo JVM interno a 32 bit dell'oggetto.

È vero che l'oggetto si sposta durante l'esecuzione (AFAIK l'unico motivo è Garbage Collector). Ma l'hashcode non cambia.

Quindi, quando si dispone di un oggetto come questo

Person person1 = new Person(); 
person1.setName("Alex"); 

Person person2 = new Person(); 
person2.setName("Alex"); 

Person person3 = person2; 

In questo caso person1.hashCode non sarà uguale a person2.hashCode perché gli indirizzi di memoria di questi due oggetti non sono gli stessi.

Ma person2.hashCode sarà uguale a person3 perché punta allo stesso oggetto.

Quindi, se è necessario utilizzare il metodo hashCode per gli oggetti, è necessario implementarlo autonomamente.

A proposito: L'implementazione di string.hashCode è diversa. E 'qualcosa di simile: (C# sintassi)

public int hashCode(String str) 
{ 
    int h = 0; 

    for (int i = 0; i < str.Length; i++) 
    h = (h * 31) + str[i]; 

    return h; 
} 

edit: Nessun controllo di overflow è fatto qui, in modo che il hashCode può essere positivo o negativo.

1

Java non genera significativo hashCode per te, è il tuo lavoro come programmatore per generare un utile hashCode. L'impostazione predefinita hashCode è solo la posizione di memoria.

+3

Preciso: l'hashcode predefinito si basa sulla posizione di memoria * la prima volta che il metodo viene chiamato * per l'oggetto; vedi @ risposta di Pascal. –

+0

Buon punto, debitamente annotato. – fastcodejava

4

Object.hashCode() utilizza System.identityHashCode() che si basa su un numero ID per un dato oggetto.

1

La funzione HashCode() ha diverse opzioni per la creazione di un codice hash. Imposta il parametro di avvio JVM.Funzione, che creano hashCode() scritto su C++, e si può vedere il codice here

  • HashCode == 0: restituisce semplicemente numeri casuali senza alcun rapporto con cui in memoria si trova l'oggetto. Per quanto posso capire, la lettura/scrittura globale del seme non è ottimale per i sistemi con molti processori .
  • HashCode == 1: Conta i valori del codice hash, non è sicuro a quale valore iniziano, ma sembra piuttosto alto.
  • HashCode == 2: Restituisce sempre lo stesso identico codice hash di identità di 1. Questo può essere utilizzato per testare il codice che si basa sull'identità dell'oggetto. Il motivo per cui JavaChampionTest ha restituito l'URL di Kirk nell'esempio sopra è che tutti gli oggetti restituivano lo stesso codice hash.
  • HashCode == 3: Conta i valori del codice hash, a partire da zero. È non sembra essere thread-safe, quindi più thread possono generare oggetti con lo stesso codice hash.
  • HashCode == 4: Questo sembra avere qualche relazione con la posizione di memoria in cui è stato creato l'oggetto.
  • HashCode> = 5: Questo è l'algoritmo predefinito per Java 8 e ha un seme per-thread per-thread. Usa lo schema xor-shift di Marsaglia per produrre numeri pseudo-casuali .

Le informazioni intrapresa dal here

+2

Come è questa una risposta alla domanda dell'OP? Questo potrebbe essere stato un commento. – Mike

+0

Perché il mio record non ha risposto? –

+0

Questa è una risposta molto migliore alla domanda con la modifica che hai aggiunto. Peccato che l'OP scelga ancora un percorso diverso. – Mike

Problemi correlati