Karena ada beberapa kebingungan tentang algoritma mana yang digunakan HashMap Java (dalam implementasi Sun / Oracle / OpenJDK), berikut cuplikan kode sumber yang relevan (dari OpenJDK, 1.6.0_20, di Ubuntu):
/**
* Returns the entry associated with the specified key in the
* HashMap. Returns null if the HashMap contains no mapping
* for the key.
*/
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;
}
Metode ini (kutipan dari baris 355 hingga 371) dipanggil saat mencari entri dalam tabel, misalnya dari get()
, containsKey()
dan beberapa lainnya. Perulangan for di sini melewati daftar tertaut yang dibentuk oleh objek entri.
Berikut kode untuk objek entri (baris 691-705 + 759):
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
final int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
// (methods left away, they are straight-forward implementations of Map.Entry)
}
Tepat setelah ini muncul addEntry()
metode:
/**
* Adds a new entry with the specified key, value and hash code to
* the specified bucket. It is the responsibility of this
* method to resize the table if appropriate.
*
* Subclass overrides this to alter the behavior of put method.
*/
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);
}
Ini menambahkan Entri baru di depan keranjang, dengan tautan ke entri pertama yang lama (atau nol, jika tidak ada). Demikian pula, removeEntryForKey()
metode ini menelusuri daftar dan menangani hanya menghapus satu entri, membiarkan sisa daftar tetap utuh.
Jadi, berikut adalah daftar entri yang ditautkan untuk setiap keranjang, dan saya sangat ragu ini berubah dari _20
menjadi _22
, karena ini seperti ini dari 1.2 ke atas.
(Kode ini adalah (c) 1997-2007 Sun Microsystems, dan tersedia di bawah GPL, tetapi untuk menyalin lebih baik gunakan file asli, yang terdapat di src.zip di setiap JDK dari Sun / Oracle, dan juga di OpenJDK.)