2015-10-16 10 views
6

this blog entry'a göre, HashMap zaten alınmış olan bir hashcode'a ait hashCode() (hash() adı verilen) kendi uygulamasını yeniden uygulamaktadır. Daha sonra anahtar boş değilse key.hashCode() HashValue döndükten sonra, hat 4HashMap'in hash() ishCode() adında kendi iç uygulaması nasıl ve nasıl oluyor?

gibi görünecek şekilde

, bu, yukarıda belirtilen yöntemle, yani key.hashCode() hat: 4, temel nesne üzerinde hashfunction arayacak

int hash = karma (HashValue)

ve şimdi, kendi karma işlevi içine HashValue döndü uygular.

Neden hash değerini (hashValue) kullanarak tekrar hesapladığımızı merak edebiliriz. Cevap, kötü kalite karma> işlevlerine karşı savunur.

doğru yeniden atamakta hashcodes hashmap miyim? HashMap nesneleri saklayabilir, ancak bir hashCode nesnesini atayan mantığa erişemez. Örneğin, hash() muhtemelen aşağıdaki hashCode() uygulanması arkasındaki mantığı entegre edemedi:

public class Employee { 
protected long employeeId; 
protected String firstName; 
protected String lastName; 

public int hashCode(){ 
    return (int) employeeId; 
} 

} 
+3

Olası kopyalar [anlama garip Java hash fonksiyonu] (http://stackoverflow.com/questions/9335169/understanding-strange-java-hash-function) – Nayuki

+1

karma 'uygulanmasını Tahmin @NayukiMinase()' 1.8.0_51 sürümü farklı/daha basit olduğundan (cevabıma bakın) zamanla değişti. – Andreas

cevap

13

hash() gerçek karma kodundan "gelişmiş" hash kodu elde yüzden eşit girdi daima jdk1 dan (eşit çıkış olacaktır .8.0_51):

static final int hash(Object key) { 
    int h; 
    return (key == null) ? 0 : (h = key.hashCode())^(h >>> 16); 
} 

karma kod geliştirme ihtiyacı neden olarak, yöntemin javadoc okuyun:

hesaplar key.hashCode() bir d yayılırsa (XORs) daha yüksek bit parçaları azalır. Tabloda, iki maskelemenin gücü kullanıldığından, yalnızca geçerli maskenin üzerindeki bitlerden farklı olan karma kümeleri her zaman çakışacaktır. (Bilinen örnekler arasında, küçük tablolarda ardışık tam sayıları tutan Float anahtarlarının kümeleri bulunur.) Bu nedenle, daha yüksek bitlerin etkisini aşağı doğru yayılan bir dönüşüm uygularız. Hız, fayda ve bit yayılma kalitesi arasında bir fark vardır. Birçok ortak karma takım zaten makul bir şekilde dağılmış olduğundan (bu yüzden yayılmadan faydalanmayın), ve ağaçlarda büyük çarpışma kümeleriyle başa çıkmak için ağaç kullandığımız için, sistematik kayıpları azaltmak için mümkün olan en ucuza bazı kaydırılmış bitleri, aksi halde, tablo sınırları nedeniyle indeks hesaplamalarında asla kullanılmayacak olan en yüksek bitlerin etkisini dahil etmek.

ait
+2

Başka bir şekilde söylemek gerekirse, 'HashMap' sınıfı işlenmemiş "hashCode()" değerlerini nesnelerinden alır ve dağıtımı daha da kolaylaştırmaya çalışmak için bire bir "beyazlatma" dönüşümü uygular. – Nayuki

+0

@Andreas Çözümü kabul ettim! Teşekkürler. Bana, ya da belki de, iki maskenin gücünün ne olduğunu açıklayabilir misiniz? Sıfır üretilen terim için google araması. – Muno

+1

@Muno İkiden fazla maskeleme, hashtable boyutunun her zaman iki (2, 4, 8, 16, 32, ...) bir güç olduğu gerçeğini ifade eder, bu nedenle hashtable kepçesini hesaplamak için basit bir bit maskesi işlemi Modül işleminden ('' '' '' '' '' '' '] daha hızlı olan (32 nolu hashtabl boyutu için' h & 0x1F' gibi) gerçekleştirilebilir. – Andreas

İlgili konular