HashMap和有序LinkedHashMap實現對比
阿新 • • 發佈:2019-01-04
LinkedHashMap:LinkedHashMap簡單來說是一個有序的HashMap,其是HashMap的子類,HashMap是無序的。接下來我們通過對比分析HashMap和LinkedHashMap來了解一下LinkedHashMap是如何實現有序的。首先HashMap及子類LinkedHashMap都提供了一個數組。
Node<K,V>[] table
不同key的hash值是分佈在這個陣列中的,key值不同,經過hash計算的hash值相同的話節點會作為相同hash值節點的next節點LinkedHashMap提供的節點添加了兩個屬性before和after節點,用來生成雙向迴圈列表的,這樣每次在Map中新增值都會追加到連結串列的最後一位,這樣就按照插入順序生成了一個連結串列class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; }
在LinkedHashMap中添加了連結串列的head和tail節點class Entry<K,V> extends HashMap.Node<K,V> { Entry<K,V> before, after; Entry(int hash, K key, V value, Node<K,V> next) { super(hash, key, value, next); } }
transient LinkedHashMap.Entry<K,V> head;
transient LinkedHashMap.Entry<K,V> tail;
總結:LinkedHashMap實現有序key值的關鍵就是根據插入順序另外維護了一個按照插入順序作為標記的雙向迴圈列表,這樣在獲取所有資料進行迴圈獲取時獲取到的資料就是有序的資料。
LinkedHashMap從迭代器獲取到的資料就是有序的
HashMap從迭代器中獲取到的資料就是hash值的相對排序的資料LinkedHashIterator() { next = head; expectedModCount = modCount; current = null; } public final boolean hasNext() { return next != null; } final LinkedHashMap.Entry<K,V> nextNode() { LinkedHashMap.Entry<K,V> e = next; if (modCount != expectedModCount) throw new ConcurrentModificationException(); if (e == null) throw new NoSuchElementException(); current = e; //獲取雙向連結串列的下一個資料 next = e.after; return e; }
HashIterator() {
expectedModCount = modCount;
Node<K,V>[] t = table;
current = next = null;
index = 0;
if (t != null && size > 0) { // advance to first entry
do {} while (index < t.length && (next = t[index++]) == null);
}
}
public final boolean hasNext() {
return next != null;
}
final Node<K,V> nextNode() {
Node<K,V>[] t;
Node<K,V> e = next;
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
if (e == null)
throw new NoSuchElementException();
//從不斷的從table中獲取資料,table
if ((next = (current = e).next) == null && (t = table) != null) {
do {} while (index < t.length && (next = t[index++]) == null);
}
return e;
}
總結:從上面兩段HashMap和LinkedHashMap迭代器實現就可以看出LinkedHashMap的實現原理了,簡單來說就是訪問佇列。