Boolean.hashCode ()


122

hashCode()Sınıf Boolean yöntemi şöyle uygulanır:

public int hashCode() {
    return value ? 1231 : 1237;
}

Neden 1231 ve 1237 kullanıyor? Neden başka bir şey olmasın?


1
Bu iki sayı yeterince büyük asal sayılardır. Daha fazla bilgi için lütfen Wikipedia'daki Karma Tablosu hakkındaki makaleyi okuyun .
Boris Pavlović

Yanıtlar:


140

1231 ve 1237 yalnızca iki (yeterince büyük) keyfi asal sayıdır . Diğer iki büyük asal sayı iyi sonuç verir.

Neden asal?
Bir saniye için kompozit sayıları (asal olmayanlar) seçtiğimizi varsayalım, örneğin 1000 ve 2000. Booleanları bir hash tablosuna eklerken, true ve false , kova 1000 % Nyanıtına 2000 % N(burada kova Nsayısıdır) gider .

Şimdi dikkat edin

  • 1000 % 8 aynı kova 2000 % 8
  • 1000 % 10 aynı kova 2000 % 10
  • 1000 % 20 aynı kova 2000 % 20
  • ....

başka bir deyişle, birçok çarpışmaya yol açacaktır .

Bunun nedeni, 1000'in (2 3 , 5 3 ) çarpanlara ayrılması ve 2000'in (2 4 , 5 3 ) çarpanlara ayrılması çok sayıda ortak faktöre sahip olmasıdır. Bu nedenle, kepçe boyutuyla herhangi bir ortak faktöre sahip olma ihtimalleri düşük olduğundan asal sayılar seçilir.

Neden büyük asal sayılar. 2 ve 3 yapmaz mı?
Bileşik nesneler için karma kodlar hesaplanırken, bileşenler için karma kodların eklenmesi yaygındır. Çok sayıda grup içeren bir karma kümede çok küçük değerler kullanılırsa, nesnelerin eşit olmayan bir şekilde dağılması riski vardır.

Çarpışmalar önemli mi? Booleanların zaten iki farklı değeri var mı?
Haritalar, diğer nesnelerle birlikte boole içerebilir. Ayrıca, Drunix tarafından belirtildiği gibi, bileşik nesnelerin karma işlevlerini oluşturmanın yaygın bir yolu, alt bileşenlerin karma kodu uygulamalarını yeniden kullanmaktır; bu durumda, büyük asalları döndürmek iyidir.

İlgili sorular:


1
Sanırım bunlar yeterince büyük. 1'den büyük bir gcd elde etmek için en az 2*1231 = 2462kova gerekir . Böyle bir durumda çarpışmalar sorun olur mu?
aioobe

2
Bir int'e neyin sığabileceği düşünüldüğünde gerçekten "oldukça büyük" olmamaları ilginçtir. Sanırım JDK Hashtable ile iyi çalışacak kadar büyükler, ancak yine de hesaplama maliyetlerini en aza indirecek kadar küçükler.
Thilo

2
Evet, onlar değil bu da bana vurdu bu büyük. Ama daha büyük asal sayıların daha yüksek bir maliyet olduğuna inanıyor musunuz?
aioobe

3
@Thilo, çarpışmadan önce birden fazla 1231 * 1237 = 1,522,747 kovaya ihtiyacınız olacak, bu yeterince büyük
cırcır ucube

2
Kova sayısıyla çarpışmalara yol açmanın aslında boole ile ilgili bir sorun değil, daha çok bir kompozit nesnenin hashcode'unu nasıl elde ettiğimize dair yaygın bir yapı, yani bileşenlerin karma kodlarını bazı sabitlerle çarparak ve bunları toplayarak söyleyebilirim.
Drunix

2

Yukarıda söylenenlere ek olarak, geliştiricilerden küçük bir paskalya yumurtası da olabilir:

doğru: 1231 => 1 + 2 + 3 + 1 = 7

7 - Avrupa geleneklerinde şanslı bir sayıdır;

yanlış: 1237 => 1 + 2 + 3 + 7 = 13

13 (aka Şeytan'ın düzinesi) - şanssız sayı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.