LinkedHashMap理解
注: 下面的源码理解均基于jdk1.8的源码
HashMap是常用的数据集合,但是是无序, LinkedHashMap就是在HashMap上进行的一种扩展,在HashMap特性的基础上增加了有序这个特性(还可以根据最新使用自动排序)设计十分巧妙
1 LinkedHashMap继承自HashMap
public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> {
2 LinkedHashMap 每个节点Node
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); } }
LinkedHashMap 的node继承了HashMap的node,在原来的基础上增加了before和after引用,实现了双向链表
3 LinkedHashMap 存储结构还是HashMap的数组,每个node通过链表链接,LinkedHashMap 并没有重新put方法,而是在newNode()方法,与HashMap不同的是在HashMap新加节点的基础上(给数组index对应的赋值),设置了after,before引用,形成了链表
Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) { LinkedHashMap.Entry<K,V> p = new LinkedHashMap.Entry<K,V>(hash, key, value, e); linkNodeLast(p); return p; }
4 LinkedHashMap get方法进行了重新,不过在不使用accessOrder的时候实现还是HashMap的实现,直接使用hash获取index
public V get(Object key) { Node<K,V> e; if ((e = getNode(hash(key), key)) == null) return null; if (accessOrder) afterNodeAccess(e); return e.value; }
5 遍历LinkedHashMap jdk1.8提供的forEach是直接遍历链表,1.8之前的写法entrySet()进行遍历, LinkedHashMap 重写了entrySet()方法
public Set<Map.Entry<K,V>> entrySet() { Set<Map.Entry<K,V>> es; return (es = entrySet) == null ? (entrySet = new LinkedEntrySet()) : es; }
返回的是一个有序的LinkedEntrySet,确保返回的数据是有序的
总结: 感觉linkedHashMap的扩展做的很巧妙,既不失HashMap的特性,有巧妙的扩展出了新特性,这也是我们自己代码设计可以借鉴的地方
上一篇: java akka
下一篇: java高并发下的唯一性验证