`

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的特性,有巧妙的扩展出了新特性,这也是我们自己代码设计可以借鉴的地方

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics