[英]How do Hashmaps, Treemaps and LinkedHashmaps work in Java?
我對地圖有各種疑問:
我一直在閱讀API文檔,但是由於我是編程的初學者,因此在理解它時有些困難。
迭代Hashmap時,將無法保證迭代順序。 現在為什么呢?
它們的插入順序不是按發生的時間,而是按哈希值插入的值。
例如,假設我們有一個哈希函數h(x) ,它為字符串“ Hello”返回127,為“ Zebra”返回12。 如果我們將這些鍵輸入到哈希映射中,則它們的讀取順序為“ Zebra”->(附加值),然后是“ Hello”->(附加值)。
這在HashMap
的源代碼中很明顯:
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
請注意,這是哈希實際執行和代表的簡化版本。 可能是哈希值存在沖突,並且需要以某種方式解決沖突。 這是指底漆; 鍵是按其哈希順序插入的,但是如果您的哈希函數存在缺陷或您對對象的哈希沒有很好的價值,則可能會遇到異常行為。
為什么Hashmap比Treemap更快?
哈希操作不依賴於整個集合的大小。 回想一下, h(x)僅基於我們要插入的單個值進行運算。 如果要在TreeMap
插入元素,則必須考慮它們所處的自然順序-這涉及遍歷結構以找到要插入的位置,還可能涉及重新平衡或重新組織結構以確保平衡。保存。
TreeMap
的put
方法的源代碼還有很多 。
public V put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
compare(key, key); // type (and possibly null) check
root = new Entry<>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
@SuppressWarnings("unchecked")
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
LinkedHashMaps如何工作,它們如何維護順序? 是因為它們有一個雙向鏈接的列表,其中包含有關在條目之前和之后存儲哪個條目的信息?
您可以自己閱讀源代碼 ,但主要內容如下:
可以這樣想:使用哈希函數確保鍵是唯一的,如果是,則立即將其及其值插入列表中。 這樣,既保留了順序又保留了唯一性。
簡而言之:映射和集合通常是未排序的數據結構。 如果要“排序集”,則最好使用列表或數組。
您的問題更多是關於數據結構的,而不是真正特定的問題或與Java相關的編程問題,因此,您應該從閱讀這些問題開始。 (對不起,作為答復:發表評論需要50次發言)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.