Java'nın HashMap'in hangi algoritmayı (Sun / Oracle / OpenJDK uygulamasında) kullandığı konusunda bazı karışıklıklar olduğu için, burada ilgili kaynak kodu parçacıkları (Ubuntu'da OpenJDK, 1.6.0_20'den):
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key.hashCode());
for (Entry<K,V> e = table[indexFor(hash, table.length)];
e != null;
e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
Bu yöntem, örneğin, tablosunda bir giriş aranırken olarak adlandırılır (alıntı hatlar 371 ile 355 dan) get()
, containsKey()
ve diğerleri. Buradaki for döngüsü, giriş nesneleri tarafından oluşturulan bağlantılı listeden geçer.
Giriş nesnelerinin kodu (691-705 + 759 satırları):
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
final int hash;
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
}
Hemen ardından şu addEntry()
yöntem gelir :
void addEntry(int hash, K key, V value, int bucketIndex) {
Entry<K,V> e = table[bucketIndex];
table[bucketIndex] = new Entry<K,V>(hash, key, value, e);
if (size++ >= threshold)
resize(2 * table.length);
}
Bu, eski ilk girişe (veya böyle bir giriş yoksa boş değer) bir bağlantıyla birlikte yeni Girişi paketin önüne ekler . Benzer şekilde, removeEntryForKey()
yöntem listeden geçer ve listenin geri kalanının bozulmadan kalmasına izin vererek yalnızca bir girişi silmeye özen gösterir.
Yani, burada her bir bölüm için bir bağlantılı giriş listesi ve çok bu değişti şüphe _20
etmek _22
Üzerinde 1.2 den böyle olduğu için.
(Bu kod (c) 1997-2007 Sun Microsystems'dir ve GPL altında mevcuttur, ancak kopyalamak için Sun / Oracle'dan her JDK'da ve ayrıca OpenJDK'da src.zip'de bulunan orijinal dosyayı daha iyi kullanın.)