回答
它基本上是這樣的:
this is the main array
↓
[Entry] → Entry → Entry ← here is the linked-list
[Entry]
[Entry] → Entry
[Entry]
[null ]
[null ]
所以,你必須在主數組,其中每個索引對應於一些散列值(mod
'ed *爲數組的大小)。
然後他們每個人都會指向相同的哈希值(再次mod
「版。*)的下一個條目。這是鏈表進入的地方。
*:作爲技術說明,it's first hashed with a different function之前是mod
'編輯,但作爲一個基本的實現,只是modding會起作用。
請注意,由於java 8,桶中的LinkedList如果太大,可以用TreeMap替換。看到這裏:http://www.nurkiewicz.com/2014/04/hashmap-performance-improvements-in.html – RobAu
散列表的條目存儲在「桶」中:每個散列表都有一個Array,並且在該Array中根據關鍵碼散列碼(例如position = hashcode%arraysize)將條目放置在一個位置。
如果不止一個條目在同一個桶的條目存儲在一個鏈表結束(見Dukelings答案)。因此,桶比喻:每個數組條目是一個「桶」,你只需要在所有匹配鍵中轉儲。
你,因爲你需要在這個列表訪問隨機位置使用的桶陣列以獲得deried「固定時間」的行爲。而內鬥,你必須遍歷所有元素,直到反正findeing所需的密鑰,所以你可以使用一個鏈表,因爲它更容易追加到(無需調整大小)。
這也顯示了良好的散列函數的需要,因爲如果所有的鍵散列到只有幾個值,你會得到龍鏈表來搜索和大量的(快速訪問)空水桶。
HashMap具有HashMap.Entry對象的數組:
/**
* The table, resized as necessary. Length MUST Always be a power of two.
*/
transient Entry<K,V>[] table;
我們可以說是進入一個單向鏈表(例如HashMap.Entry聯動被稱爲「鬥」),但它實際上不是一個java.util.LinkedList。
見自己:
static class Entry<K,V> implements Map.Entry<K,V> {
final K key;
V value;
Entry<K,V> next;
int hash;
/**
* Creates new entry.
*/
Entry(int h, K k, V v, Entry<K,V> n) {
value = v;
next = n;
key = k;
hash = h;
}
public final K getKey() {
return key;
}
public final V getValue() {
return value;
}
public final V setValue(V newValue) {
V oldValue = value;
value = newValue;
return oldValue;
}
public final boolean equals(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry e = (Map.Entry)o;
Object k1 = getKey();
Object k2 = e.getKey();
if (k1 == k2 || (k1 != null && k1.equals(k2))) {
Object v1 = getValue();
Object v2 = e.getValue();
if (v1 == v2 || (v1 != null && v1.equals(v2)))
return true;
}
return false;
}
public final int hashCode() {
return (key==null ? 0 : key.hashCode())^
(value==null ? 0 : value.hashCode());
}
public final String toString() {
return getKey() + "=" + getValue();
}
/**
* This method is invoked whenever the value in an entry is
* overwritten by an invocation of put(k,v) for a key k that's already
* in the HashMap.
*/
void recordAccess(HashMap<K,V> m) {
}
/**
* This method is invoked whenever the entry is
* removed from the table.
*/
void recordRemoval(HashMap<K,V> m) {
}
}
HashMap的內部使用條目來存儲鍵值對。條目屬於LinkedList類型。
條目包含以下 - >
K鍵,
V值和
條目下一個>即在桶的該位置下一個條目。
static class Entry<K, V> {
K key;
V value;
Entry<K,V> next;
public Entry(K key, V value, Entry<K,V> next){
this.key = key;
this.value = value;
this.next = next;
}
}
的HashMap圖 -
來源:http://www.javamadesoeasy.com/2015/02/hashmap-custom-implementation.html
- 1. 轉換陣列散列使用grep和映射在Perl
- 2. 如何從散列映射
- 3. 散列集內部可以使用其他集合而不是散列映射
- 4. 如何將內存映射到散列映射到文件
- 5. 紅寶石:建立通過映射陣列散列到陣列
- 6. Knockout映射插件不映射陣列內部模型
- 7. 如何使用Octave創建和訪問字典(或映射或散列表)
- 8. 使用SHA1作爲鏈中最內部散列的散列
- 9. 搜索PHP ASSOC陣列(散列映射)如MySQL的
- 10. 在散列表內部檢索列表。
- 11. 限定使用散列映射
- 12. 如何映射散列數組?
- 13. 如何映射散列鍵與c#中的值列表?
- 14. java多映射陣列列表
- 15. Python映射陣列
- 16. 陣列不映射
- 17. JPA陣列映射
- 18. Dapper:如何在內部類模型中映射表中的列?
- 19. 如何使用列表映射鍵值?
- 20. 在Matlab中使用邏輯陣列映射陣列
- 21. 陣列映射在PHP
- 22. 如何在內部陣列
- 23. 散列映射鍵 - 如果存在映射
- 24. 散列用鏈表
- 25. 敲除:陣列的部分映射
- 26. 1D陣列到2D陣列映射
- 27. 將2D陣列映射到1D陣列
- 28. 如何映射列表.__ contains__?
- 29. 陣列映射內存選定區域
- 30. 使用迭代將陣列列表排序映射到地圖
你爲什麼看'HashSet'當你想了解'HashMap'的實現? 'HashMap'使用鏈表,但不使用類LinkedList。 –
閱讀源代碼?它實際上充滿了豐富的評論... – vikingsteve
@SotiriosDelimanolis我只是通過所有集合的內部實現,學習hashset以及hashmap是好的我猜 – dexterousashish