Java集合系列---LinkedHashMap源码解析

5 篇文章 0 订阅
4 篇文章 0 订阅

1 首先来看一下LinkedHashMap的继承关系

public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V>

可以看出LinkedHashMap是继承了HashMap,它主要在链表的基础上增加了一个双向链表,重复的key值插入不会改变顺序,适用于使用者需要返回一个顺序相同的map对象的情况。允许放入key和value都为null的元素
在这里插入图片描述
2 成员变量
链表节点基本上是继承HashMap的节点,并在原基础上添加了两个属性,用于双向链表

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);
        }
    }
   /**
 * 双向链表的首节点
 */
transient LinkedHashMap.Entry<K,V> head;
 
/**
 * 尾节点
 */
transient LinkedHashMap.Entry<K,V> tail;
 
/**
 * 排序规则方式
 * true 按访问顺序排序 
 * false 默认按插入顺序排序
 */
final boolean accessOrder;

3 构造方法

构造方法
1.
 
/**
 * 调用HashMap的构造方法
 */
public LinkedHashMap() {
    super();
    //默认按插入顺序排序
    accessOrder = false;
}
2.
 
/**
 * 调用HashMap的构造方法
 */
public LinkedHashMap(int initialCapacity) {
    super(initialCapacity);
    //默认按插入顺序排序
    accessOrder = false;
}
3.
 
/**
 * 调用HashMap的构造方法
 */
public LinkedHashMap(int initialCapacity, float loadFactor) {
    super(initialCapacity, loadFactor);
    //默认按插入顺序排序
    accessOrder = false;
}
4.
 
/**
 * 调用HashMap的构造方法
 */
public LinkedHashMap(Map<? extends K, ? extends V> m) {
    super();
    //默认按插入顺序排序
    accessOrder = false;
    putMapEntries(m, false);
}
5.
 
/**
 * 调用HashMap的指定参数的构造方法
 * 并且指定排序方式
 */
public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder) {
    super(initialCapacity, loadFactor);
    this.accessOrder = accessOrder;
}

4 核心方法
LinkedHashMap的添加删除基本都与HashMap一样,只是在添加和删除之后还增加了调整的方法
在访问过后将链表移至尾部

void afterNodeAccess(Node<K,V> e) { // move node to last
    LinkedHashMap.Entry<K,V> last;
    //当accessOrder为true 并且e不是最后一个节点的时
    if (accessOrder && (last = tail) != e) {
        //a为p的下一个节点
        //b为p的上一个节点
        LinkedHashMap.Entry<K,V> p =
            (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
        //p的下一个节点置null
        p.after = null;
        //b==null,即当前节点为首节点,更新首节点为a
        if (b == null)
            head = a;
        else//当前节点不是首节点,修改b的下一个节点为a
            b.after = a;
        if (a != null) //a!=null,即当前结点不是尾节点
            a.before = b;//更新a的上一个节点为b
        else
            last = b;//最后一个节点更新为b
        if (last == null)//如果最后一个节点为null
            head = p;//首节点更新为p
        else {
            p.before = last;//p的上一个节点更新为最后一个节点
            last.after = p;//最后一个节点的下一个节点更新为p
        }
        //尾节点修改为p
        tail = p;
        //操作次数增加
        ++modCount;
    }
}

删除一个节点时自动调整

void afterNodeRemoval(Node<K,V> e) { // unlink
    //a为p的下一个节点
    //b为p的上一个节点
    LinkedHashMap.Entry<K,V> p =
        (LinkedHashMap.Entry<K,V>)e, b = p.before, a = p.after;
    p.before = p.after = null;
 
    if (b == null) //b为null,即当前节点为首节点
        head = a;//更新首节点为a
    else//即当前节点不是首节点
        b.after = a;//更新b的下一个节点为a
    if (a == null)//a为null,当前节点为尾节点
        tail = b;//更新尾节点为b
    else//即当前节点不是尾节点
        a.before = b;//更新a的上一个节点为b
}

图片参考博客:https://www.php.cn/java-article-359154.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值