##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; }