LinkedHashMap介绍

LinkedHashMap继承自HashMap。可以实现有序的map,而hashmap是无序的。所谓有序就是指迭代的时候按照某种顺序迭代。比如插入顺序,或者最近访问顺序。而不是按照key或者value的大小值排序。

其中默认是按插入顺序排序,也可以按照最近访问排序来遍历LinkedHashMap。

 * <p>A special {@link #LinkedHashMap(int,float,boolean) constructor} is
 * provided to create a linked hash map whose order of iteration is the order
 * in which its entries were last accessed, from least-recently accessed to
 * most-recently (<i>access-order</i>).  This kind of map is well-suited to
 * building LRU caches. 

LinkedHashMap实现了Map接口,而且是以hash table和linked list相结合的方式实现,所谓的“hash table和linked list相结合”是指LinkedHashMap底层还是使用了一个数组结合hash来存储,跟HashMap一致。所谓的实现了linked list,是指LinkedHashMap内部维护一个双向列表,主要是通过如下方式实现双向列表的:

首先重新定义了Map中的Node,注意跟HashMap中的Node区分,增加了指向前一个和后一个节点的指针:


    /**
     * HashMap.Node subclass for normal LinkedHashMap entries.
     */
    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);
        }
    }

其次,定义了两个指针变量,分别只想链表的头和尾


    /**
     * The head (eldest) of the doubly linked list.
     */
    transient LinkedHashMap.Entry<K,V> head;

    /**
     * The tail (youngest) of the doubly linked list.
     */
    transient LinkedHashMap.Entry<K,V> tail;

然后在插入新元素的时候, 会调用父类HashMap的put(key, value)方法,然后父类会调用子类LinkedHashMap的new Node方法来创建新节点,并切完整链表链接操作。

 Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {
        LinkedHashMap.Entry<K,V> p =
            new LinkedHashMap.Entry<>(hash, key, value, e);
        linkNodeLast(p);
        return p;
    }

    // internal utilities

    // link at the end of list
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {
        LinkedHashMap.Entry<K,V> last = tail;
        tail = p;
        if (last == null)
            head = p;
        else {
            p.before = last;
            last.after = p;
        }
    }

由于LinkedHashMap地层仍采用哈希数组的方式来存储数据,所以插入和查找的速度跟HashMap不差上下。以下是官方说法:

* <p>This class provides all of the optional {@code Map} operations, and
* permits null elements.  Like {@code HashMap}, it provides constant-time
* performance for the basic operations ({@code add}, {@code contains} and
* {@code remove}), assuming the hash function disperses elements
* properly among the buckets.  Performance is likely to be just slightly
* below that of {@code HashMap}, due to the added expense of maintaining the
* linked list, with one exception: Iteration over the collection-views
* of a {@code LinkedHashMap} requires time proportional to the <i>size</i>
* of the map, regardless of its capacity.  Iteration over a {@code HashMap}
* is likely to be more expensive, requiring time proportional to its
* <i>capacity</i>.

而且按照官方说法, LinkedHashMap遍历只跟LinkedHashMap中实际拥有的节点个数有关,而与Capacity没关系,而HashMap就做不到这一点,HashMap的遍历话费事件跟Capacity的大小成正比,这是因为LinkedHashMap有指针,遍历时通过指针来遍历,而HashMap需要遍历保存数据的数组的每一个元素,数组越大, Capacity越大,遍历时间越久。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值