LinkedHashMap

1. 简介

LinkedHashMap 可以认为是 HashMap+LinkedList,它既使用 HashMap 操作数据结构,又使用 LinkedList 维护插入元素的先后顺序,内部采用双向链表(doubly-linked list)的形式将所有元素( entry )连接起来。

LinkedHashMap 继承了 HashMap,允许放入 key 为 null 的元素,也允许插入 value 为 null 的元素。从名字上可以看出该容器是 LinkedList 和 HashMap 的混合体,也就是说它同时满足 HashMap 和 LinkedList 的某些特性,可将 LinkedHashMap 看作采用 Linkedlist 增强的 HashMap。

打开 LinkedHashMap 源码,可以看到主要三个核心属性:

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>{
	/**双向链表的头节点*/
	transient LinkedHashMap.Entry<K,V> head;

	/**双向链表的尾节点*/
	transient LinkedHashMap.Entry<K,V> tail;

	/**
	 * 1、如果accessOrder为true的话,则会把访问过的元素放在链表后面,放置顺序是访问的顺序
	 * 2、如果accessOrder为false的话,则按插入顺序来遍历
	 */
    final boolean accessOrder;
}

LinkedHashMap  在初始化阶段,默认按插入顺序来遍历

public LinkedHashMap() {
    super();
    accessOrder = false;
}

LinkedHashMap 采用的 Hash 算法和 HashMap 相同,不同的是,它重新定义了数组中保存的元素 Entry,该 Entry 除了保存当前对象的引用外,还保存了其上一个元素 before 和下一个元素 after 的引用,从而在哈希表的基础上又构成了双向链接列表。源码如下:

static class Entry<K,V> extends HashMap.Node<K,V> {
	//before指的是链表前驱节点,after指的是链表后驱节点
    Entry<K,V> before, after;
    Entry(int hash, K key, V value, Node<K,V> next) {
        super(hash, key, value, next);
    }
}

                    

可以直观的看出,双向链表头部插入的数据为链表的入口,迭代器遍历方向是从链表的头部开始到链表尾部结束。

       除了可以保迭代历顺序,这种结构还有一个好处:迭代 LinkedHashMap 时不需要像 HashMap 那样遍历整个 table,而只需要直接遍历 header 指向的双向链表即可,也就是说 LinkedHashMap 的迭代时间就只跟 entry 的个数相关,而跟 table 的大小无关。

2.  get方法

      get 方法根据指定的 key 值返回对应的 value。该方法跟 HashMap.get() 方法的流程几乎完全一样,默认按照插入顺序遍历。如果 accessOrdertrue的话,会把访问过的元素放在链表后面,放置顺序是访问的顺序。

3.  put 方法

       put(K key, V value) 方法是将指定的 key, value 对添加到 map 里。该方法首先会调用 HashMap 的插入方法,同样对 map 做一次查找,看是否包含该元素,如果已经包含则直接返回,查找过程类似于 get() 方法;如果没有找到,将元素插入集合。

4. remove方法

         remove(Object key) 的作用是删除 key 值对应的 entry,该方法实现逻辑主要以 HashMap 为主,首先找到 key 值对应的 entry,然后删除该 entry(修改链表的相应引用),查找过程跟 get() 方法类似,最后会调用 LinkedHashMap 中覆写的方法,将其删除!

总结

        LinkedHashMap 继承自 HashMap,所有大部分功能特性基本相同,二者唯一的区别是 LinkedHashMap 在 HashMap 的基础上,采用双向链表(doubly-linked list)的形式将所有 entry 连接起来,这样是为保证元素的迭代顺序跟插入顺序相同。主体部分跟 HashMap 完全一样,多了 header 指向双向链表的头部,tail 指向双向链表的尾部,默认双向链表的迭代顺序就是 entry 的插入顺序。

来源于Java极客技术 ,作者炸鸡可乐

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值