JDK源码学习04-寄生虫LinkedHashMap

6 篇文章 0 订阅
2 篇文章 1 订阅

活久见的LinkedHashMap

随便聊聊

笔者大三,在2021.1.18入职字节实习生,干了四十天就休假跑路回去上课了。最近一大段时间过的非常松懈,现在报复性疯狂发布博客,哈哈。还是决定阅读JDK源码,从集合开始,希望能够读完核心的集合、AQS、线程池在等部分,最近对Java并发比较感兴趣也比较有体会,鬼知道能不能坚持到那个时候。笔者的文章可能不够详细,但会记录下来个人觉得比较核心的内容。
联系方式:qq 754647431

LinkedHashMap简介

核心原理:

LinkedHashMap的底层结构是:由于继承而产生的HashMap父类|LinkedHashMap自己的双向链表
所以LinkedHashMap只不过是在HashMap的基础上额外维护了一个双向链表罢了,仅此而已
那么问题来了:LinkedHashMap是如何在自己实现一点点方法的基础上,利用到HashMap中呢?
-----实际上是LinkedHashMap重写了HashMap的newNode函数,额外添加了一句话linkNodeLast§;这样就实现了在插入时维护双向链表,但是删除元素非常复杂,需要仔细看源码才行。这里先放下HashMap留给LinkedHashMap的后门方法。

    # 这是HashMap留给LinkedHashMap的后门,
    // Callbacks to allow LinkedHashMap post-actions
    // 如果hashmap的节点被更新  则调用该方法
    void afterNodeAccess(Node<K,V> p) { }
    // 如果hashmap插入节点   则调用该方法
    void afterNodeInsertion(boolean evict) { }
    // 如果hashmap删除节点  则调用该方法
    void afterNodeRemoval(Node<K,V> p) { }

这是我调试的时候截的图,可以看出,LinkedHashMap按顺序存储了双向链表结构,而HashMap也按hash存储了数据,每个数据都被存储了两次,并且结构体也不同
在这里插入图片描述

  1. 我们可以发现LinkedHashMap继承于HashMap,在HashMap已经实现Map接口的情况下,LinkedHashMap仍然实现了Map接口,实现Map接口会要求LinkedHashMap实现所有Map接口的方法。
public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
  1. 我们可以发现,LinkedHashMap包含的函数非常少,甚至不包含put方法,这是因为LinkedHashMap继承了HashMap的put等方法。
    在这里插入图片描述
  2. 我们来看看LinkedHashMap如何从HashMap获取数据,来维护自己的双向链表。
  • LinkedHashMap重写了HashMap的newNode方法,每次HashMap需要插入节点的时候都需要newNode函数,这样LinkedHashMap就能够通过linkNodeLast§;来维护双向链表了。
	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;
    }

核心维护双向链表的函数

// 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;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值