##LinkedHashMap介紹安全
LinkedHashMap繼承自HashMap實現Map接口,能夠實現有序排列線程
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>
##構造方法 LinkedHashMap的構造方法和HashMap的構造方法都差很少只是每一個都加上了code
accessOrder=false
LinkedHashMap 是有序序列accessOrder肯定LinkedHashMap是基於read仍是write的訪問順序對象
##LinkedHashMap public方法 LinkedHashMap提供了尾節點的訪問,對象的copy,提供了正常的新增,替換等繼承
LinkedHashMap記錄了頭節點(head)和尾節點(tail),因此獲取head和tail都是O(1) ###containsValue 遍歷LinkedHashMap,檢查節點是否含有value接口
public boolean containsValue(Object value) { for (LinkedHashMap.Entry<K,V> e = head; e != null; e = e.after) { V v = e.value; if (v == value || (value != null && value.equals(v))) return true; } return false; }
###keySet/values/entrySet 覆蓋了父類的keySet方法,遍歷keySet線程安全hash
transient volatile Set<K> keySet;
若是keySet不存在則爲keySet從新建立對象it
public Set<K> keySet() { Set<K> ks; return (ks = keySet) == null ? (keySet = new LinkedKeySet()) : ks; }
###newNode 新增節點首先須要知道 LinkedHashMap數據節點結構,LinkedHashMap是雙向鏈表一定指定了before和afterast
static 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); } }
1.先新建節點class
LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e);
2.將節點插入到最後一個位置(linkNodeLast(p))
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) { //tail:類變量,LinkedHashMap的尾節點 LinkedHashMap.Entry<K,V> last = tail; tail = p; if (last == null) head = p; //若爲空則證實是雙向列表 else { p.before = last; //造成雙向鏈表 last.after = p; } }
###replacementNode 替換節點 1.獲取兩個節點 2.指向節點發生變化
Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) { //獲取當前節點和下一節點 LinkedHashMap.Entry<K,V> q = (LinkedHashMap.Entry<K,V>)p; LinkedHashMap.Entry<K,V> t = new LinkedHashMap.Entry<K,V>(q.hash, q.key, q.value, next); //交換節點 transferLinks(q, t); return t; }
transferLinks:將源節點和目標節點交換位置
private void transferLinks(LinkedHashMap.Entry<K,V> src, LinkedHashMap.Entry<K,V> dst) { LinkedHashMap.Entry<K,V> b = dst.before = src.before; LinkedHashMap.Entry<K,V> a = dst.after = src.after; if (b == null) head = dst; else b.after = dst; if (a == null) tail = dst; else a.before = dst; }