Data una ragionevole raccolta di oggetti, è molto probabile avere due con lo stesso codice hash. Nel migliore dei casi diventa il problema del compleanno, con uno scontro con decine di migliaia di oggetti. In pratica gli oggetti sono creati con un pool relativamente piccolo di probabili codici hash e le collisioni possono facilmente verificarsi con solo migliaia di oggetti.
L'utilizzo dell'indirizzo di memoria è solo un modo per ottenere un numero leggermente casuale. L'origine Sun JDK ha un interruttore per abilitare l'uso di un generatore di numeri casuali sicuro o una costante. Credo che IBM (usato per?) Usasse un generatore di numeri casuali veloce, ma non era affatto sicuro. La menzione nei documenti di indirizzo di memoria sembra essere di natura storica (circa dieci anni fa non era raro avere maniglie di oggetti con posizioni fisse).
Ecco alcuni codice che ho scritto qualche anno fa per dimostrare scontri:
class HashClash {
public static void main(String[] args) {
final Object obj = new Object();
final int target = obj.hashCode();
Object clash;
long ct = 0;
do {
clash = new Object();
++ct;
} while (clash.hashCode() != target && ct<10L*1000*1000*1000L);
if (clash.hashCode() == target) {
System.out.println(ct+": "+obj+" - "+clash);
} else {
System.out.println("No clashes found");
}
}
}
RFE per chiarire i documenti, perché questo viene su troppo di frequente: CR 6321873
fonte
2009-09-04 20:02:11
Se gli oggetti vengono spostati, anche i loro indirizzi non cambiano, e quindi i loro hashcode? –
@Vineet: come si "sposta" un oggetto in java? – Brian
@Brian, la preoccupazione dell'OP sembra riguardare ciò che accade durante la fase di compattazione della garbage collection. Durante la compattazione, gli oggetti possono essere spostati attraverso gli indirizzi. –