HashMap
belirli sayıda kova içerir. hashCode
Bunları hangi kovaya koyacağını belirlemek için kullanır . Basitlik uğruna, bunu bir modül olarak hayal edin.
Karma kodumuz 123456 ise ve 4 paketimiz varsa, 123456 % 4 = 0
öğe ilk kova olan Kova 1'e gider.
İşlevimiz hashCode
iyiyse, tüm kovaların bir şekilde eşit olarak kullanılması için eşit bir dağılım sağlamalıdır. Bu durumda paket, değerleri depolamak için bağlantılı bir liste kullanır.
Ancak, iyi hash işlevlerini uygulamak için insanlara güvenemezsiniz. İnsanlar genellikle zayıf hash fonksiyonları yazacak ve bu da eşit olmayan bir dağılımla sonuçlanacaktır. Ayrıca girdilerimizle şanssız kalmamız da mümkündür.
Bu dağılım ne kadar azsa, O (1) işlemlerinden o kadar uzaklaşıyoruz ve O (n) işlemlerine doğru ilerliyoruz.
HashMap uygulaması, paketler çok büyük hale gelirse, bazı paketleri bağlantılı listeler yerine ağaçlarda organize ederek bunu azaltmaya çalışır. Bu ne TREEIFY_THRESHOLD = 8
içindir. Bir kova sekizden fazla öğe içeriyorsa, bir ağaç haline gelmelidir.
Bu ağaç , muhtemelen bazı en kötü durum garantileri sunduğu için seçilen Kırmızı-Siyah bir ağaçtır . Önce hash koduna göre sıralanır. Karma kodlar aynıysa, nesneler bu arabirimi uygularsa, aksi takdirde kimlik karma kodu compareTo
yöntemini kullanır Comparable
.
Girişler haritadan kaldırılırsa, paketteki girişlerin sayısı bu ağaç yapısına artık gerek kalmayacak şekilde azalabilir. Bunun UNTREEIFY_THRESHOLD = 6
için var. Bir kepçedeki eleman sayısı altının altına düşerse, bağlantılı bir listeye geri dönebiliriz.
Son olarak MIN_TREEIFY_CAPACITY = 64
,.
Bir karma haritanın boyutu büyüdüğünde, daha fazla gruba sahip olmak için kendini otomatik olarak yeniden boyutlandırır. Küçük bir HashMap'imiz varsa, çok dolu kovalar elde etme olasılığımız oldukça yüksektir, çünkü içine bir şeyler koymak için çok fazla farklı kovaya sahip değiliz. Daha az dolu daha fazla kova ile daha büyük bir HashMap'e sahip olmak çok daha iyidir. Bu sabit, temelde HashMap'imiz çok küçükse ağaçlara kova yapmaya başlamamamızı söylüyor - bunun yerine önce daha büyük olacak şekilde yeniden boyutlandırılması gerekiyor.
Performans kazancı hakkındaki sorunuza cevap vermek için, bu optimizasyonlar en kötü durumu iyileştirmek için eklenmiştir. hashCode
İşleviniz çok iyi olmasaydı, muhtemelen bu optimizasyonlar nedeniyle yalnızca gözle görülür bir performans artışı göreceksiniz .
Kötü hashCode
uygulamalara karşı koruma sağlamak için tasarlanmıştır ve aynı zamanda kötü bir aktörün aynı kovaları işgal eden girdileri kasten seçerek bir sistemi yavaşlatmaya çalışabileceği çarpışma saldırılarına karşı temel koruma sağlar .
String
,int
karma koddan çok daha büyük bir değer alanına sahiptir , bu nedenle, çarpışmalar kaçınılmazdır. Şimdi bu, gerçek değerler gibiString
, haritaya koyduğunuz gerçek değerlere bağlı, eşit bir dağılım olsun veya olmasın. Kötü bir dağıtım, kötü şansın sonucu olabilir.