Il hashCode()metodo della classe Boolean è implementato in questo modo:
public int hashCode() {
return value ? 1231 : 1237;
}
Perché usa 1231 e 1237? Perché non qualcos'altro?
Il hashCode()metodo della classe Boolean è implementato in questo modo:
public int hashCode() {
return value ? 1231 : 1237;
}
Perché usa 1231 e 1237? Perché non qualcos'altro?
Risposte:
1231 e 1237 sono solo due numeri primi arbitrari (sufficientemente grandi) . Altri due numeri primi grandi andrebbero bene.
Perché i numeri primi?
Supponiamo per un secondo di aver scelto numeri composti (non primi), diciamo 1000 e 2000. Quando si inseriscono valori booleani in una tabella hash, true e false andrebbero nel bucket 1000 % Nresp 2000 % N(dove Nè il numero di bucket).
Ora notalo
1000 % 8 stesso secchio di 2000 % 81000 % 10 stesso secchio di 2000 % 101000 % 20 stesso secchio di 2000 % 20in altre parole, porterebbe a molte collisioni .
Questo perché la fattorizzazione di 1000 (2 3 , 5 3 ) e la fattorizzazione di 2000 (2 4 , 5 3 ) hanno tanti fattori comuni. Pertanto vengono scelti i numeri primi, poiché è improbabile che abbiano fattori comuni con la dimensione del secchio.
Perché numeri primi grandi . 2 e 3 non andrebbero bene?
Quando si calcolano i codici hash per oggetti compositi, è comune aggiungere i codici hash per i componenti. Se vengono utilizzati valori troppo piccoli in un set di hash con un numero elevato di bucket, c'è il rischio di finire con una distribuzione non uniforme degli oggetti.
Le collisioni sono importanti? I booleani hanno comunque due valori diversi?
Le mappe possono contenere valori booleani insieme ad altri oggetti. Inoltre, come sottolineato da Drunix, un modo comune per creare funzioni hash di oggetti compositi è riutilizzare le implementazioni del codice hash dei sottocomponenti, nel qual caso è bene restituire numeri primi grandi.
Domande correlate:
2*1231 = 2462bucket. Le collisioni sono un problema in una situazione del genere?