Java容器之LinkedHashMap源码分析(看看确定不点进来?进来真不点?)

本文深入剖析Java容器中的LinkedHashMap,从类的定位、数据结构、属性与内部类、构造器到维护原理,揭示其保持插入顺序的秘诀。通过源码分析,理解其如何在HashMap基础上实现双向链表,以及put、get等操作如何影响链表结构。
摘要由CSDN通过智能技术生成

  前面几篇博客Java容器之Hashtable源码分析Java容器之HashMap源码分析分别分析了HashMapHashtable的源码,此篇博客我们分析一下LinkedHashMap容器,看看它又有什么花样。

注明:以下源码分析都是基于jdk 1.8.0_221
在这里插入图片描述

一、LinkedHashMap容器概述(一图以蔽之

  LinkedHashMap类的申明如下:

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

  可以看出LinkedHashMapHashMap子类(建议先看看HashMap再来看捏 → Java容器之HashMap源码分析),大胆推测一下,LinkedHashMap底层用HashMap存储节点,只是展示给你的是一个Linked状态。

1、LinkedHashMap容器的自我定位

  看过博主前面HashMapHashtable源码分析或者了解一点Map结构的小伙伴,肯定知道HashMap的定位是单线程处理(读、写高效),Hashtable的定位是支持并发读写(引入锁机制,降低效率),那么这个LinkedHashMap的定位又是什么呢?先来看个例子:

public class Main {
   
    public static void main(String[] args) {
   
        // 新建一个linkedHashMap
        LinkedHashMap<String, String> linkedHashMap = new LinkedHashMap<>();
        // 依次插入三个key-value
        linkedHashMap.put("老王", "我是谁");
        linkedHashMap.put("老赵", "我在哪");
        linkedHashMap.put("老李", "我要干嘛");
        // 遍历输出linkedHashMap中的key-value
        for (Map.Entry<String, String> entry : linkedHashMap.entrySet()) {
   
            System.out.println(entry.getKey() + "\t" + entry.getValue());
        }
    }
}

在这里插入图片描述
  可以看出LinkedHashMap能按照插入的顺序给你输出,即一种Linked的状态,其实这就是它的最主要特点。

2、LinkedHashMap容器数据结构图

  LinkedHashMap容器比较简单,所有的key-value节点都是存在HashMap容器中(前面说过LinkedHashMap继承HashMap),只是加上beforeafter指针。一句话概括就是 LinkedHashMap = HashMap + 双链表。
在这里插入图片描述
注明:在JDK1.8中,HashMaphash桶实现引入了红黑树(参考Java容器之HashMap源码分析),但是我们此处主要是讨论LinkedHashMapLinked属性,为了方便画图,所以结构示意图没有画出来。

二、LinkedHashMap类的属性与内部类

1、Entry内部类

  在HashMap存储key-value的类为Node(属性主要包括hashkeyvalue),在LinkedHashMap类用于要记录Linked状态,所以增加一个继承Node的内部类EntryEntry类只是增加beforeafter指针而已,在LinkedHashMapEntry对象存key-value

/**
 * Entry继承HashMap.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);
    }
}

2、LinkedHashMap新增属性

  LinkedHashMap类中新增三个主要的属性,headtail分别指向外部展示的list头部、尾部,accessOrder属性的作用是list中节点顺序是否随get方法调用而改变。

/**
 * Linked list 头部
 */
transient LinkedHashMap.Entry<K,V> head;

/**
 * Linked list 尾部
 */
transient LinkedHashMap.Entry<K,V> tail;

/**
 * = true,每次调用get方法都会将查找到的key-value放入尾部
 */
final boolean accessOrder;

备注:这里的accessOrder有人翻为访问顺序,其实根本不用翻译这个词。因为它容器与插入顺序搞混,从而搞乱LinkedHashMap有序到底什么有序。你只要记住LinkedHashMapkey-value插入顺序有序,accessOrder变量的作用是调用get方法是否会将查找到的节点放入尾部即可!

三、LinkedHashMap类构造器

  LinkedHashMap类一共有5个构造器,涉及initialCapacityloadFactoraccessOrder三个参数的初始化。

/**
 * @param  initialCapacity 初始容量(hashMap.table数组长度)
 * @param  loadFactor      负载因子(hashMap中的参数,
 * 							initialCapacity * loadFactor就是HashMap容器可存放的key-value阈值,这里不再重复介绍了)
 */
public LinkedHashMap(int initialCapacity, float loadFactor) {
   
	// super关键字,调用父类HashMap的响应构造器
    super(initialCapacity, loadFactor);
    // 默认维护的list不随get方法调用改变
    accessOrder = false;
}

/**
 * @param  initialCapacity 初始容量(hashMap.table数组长度)
 */
public 
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值