LinkedHashMap是如何实现有序的

本文探讨了LinkedHashMap如何实现有序特性,与HashMap的区别在于它维护了一个双向链表。通过accessOrder标志,可以按插入顺序或访问顺序排序。在put、get和remove操作中,LinkedHashMap重写了相关方法以维护链表结构,确保有序性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.各大培训机构,价格10万的视频 Java架构师视频免费送

2.各种电子书籍经典Java书籍免费送

3.关注下方我的公众号进行免费获取

4.个人技术总结免费赠送

 

 

1.LinkedHashMap有序

 

    如果你用过HashMap那么肯定知道HashMap是不能保证有序性的,之所以HashMap不能保证有序性是因为存放数组位置的数据时根据hash函数决定的;但是有没有能够保证有序性的Map呢?那就是LinkedHashMap,下面我们通过代码来看一下HashMap的无序和LinkedHashMap的有序性。

    HashMap无序

 

 

 

    LinkedHashMap有序

 

 

 

    LinkedHashMap一共有5个构造方法,其中有4个的构造方法都是指定了accessOrder为false,只有第一个可以自定义accessOrder的状态,accessOrder实际上就是指定排序的规则;如果accessOrder为false表示根据插入的顺序进行排序,当为true的时候表示根据获取排序。可看如下实例代码

 

 

 

    插入顺序为45,55,53然后获取了55,45排序顺序变为53,44,45。

 

 

 

 

2.LinkedHashMap源码

 

    同样在看源码之前我们先看一下LinkedHashMap的继承与实现关系图。可以看到LinkedHashMap继承HashMap,同时实现了Map接口。

 

 

    LinkedHashMap对HashMap的newNode、afterNodeAccess、afterNodeInsertion方法进行都进行了重写,同时也对HashMap中的Node进行了重写增加了before和after字段。

 

 

 

 

 

 

    回到LinkedHashMap的put方法。当我们debug进入到LinkedHashMap后实际上就是调用了HashMap的put方法。

 

 

    在putVal中先判断Node是否需要为空,为空进行初始化,如果不为判断对应数组下标中是否有值,如果没有调用newNode方法。在newNode中调用linkNodeLast。

 

 

    linkNodeLast拿到尾部节点。如果尾部为空直接把第一个当前节点设置为头和尾节点,如果不为空则拿到尾部节点同时将当前节点的before设置为尾部节点即前一个节点,而将前一个节点的after设置为当前节点。这个before和after是不是就是一个双向链表的意思。

 

 

    在HashMap中实际上并没有对afterNodeInsertion方法进行任何实现,而在LinkedHashMap中做了具体的实现操作。但是在JDK8中不会执行,因为removeEldestEntry方法始终返回false。

 

 

 

 

    实际上LinkedList能够实现有序就是因为重写了Node并增加了before和after字段,同时对newNode方法进行了重写,有序就是因为before和after字段

 

3.get方法

 

    LinkedHashMap的get方法与HashMap中get方法的不同点也在于多了afterNodeAccess()方法。afterNodeAccess方法在执行时必须accessOrder为true,也就是必须是根据获取排序时才会执行。

 

 

    详细看一下afterNodeAccess是怎么实现的,afterNodeAccess实际上就是把当前获取的节点的after和before进行重新变化,也就是移动到最后面去。

 

 

 

3.remove方法

 

    reomve方法也直接使用了HashMap中的remove,LinkedHashMap重写了其中的afterNodeRemoval该方法在HashMap中没有具体实现,通过此方法在删除节点的时候调整了双链表的结构。

 

 

4.总结

 

    LinkedHashMap之所以能保证有序性是因为在HashMap的Node基础上又增加了after和before字段,相当有又是一个双向链表来维护有序性。结构如下

 

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值