《Java 编程的逻辑》笔记——第10章 Map和Set(三)

本文详细解析了Java中LinkedHashMap的有序特性,包括按插入和访问顺序排列,并探讨了其在LRU缓存中的应用。LinkedHashMap是HashMap的子类,内部通过双向链表维护顺序。此外,还介绍了LinkedHashSet的相关知识。
摘要由CSDN通过智能技术生成

声明:

本博客是本人在学习《Java 编程的逻辑》后整理的笔记,旨在方便复习和回顾,并非用作商业用途。

本博客已标明出处,如有侵权请告知,马上删除。

10.6 剖析 LinkedHashMap

之前我们介绍了 Map 接口的两个实现类 HashMap 和 TreeMap,本节来介绍另一个实现类 LinkedHashMap。它是 HashMap 的子类,但可以保持元素按插入或访问有序,这与 TreeMap 按键排序不同。

按插入有序容易理解,按访问有序是什么意思呢?这两个有序有什么用呢?内部是怎么实现的呢?本节就来探讨这些问题。从用法开始。

10.6.1 基本用法

LinkedHashMap 是 HashMap 的子类,但内部还有一个双向链表维护键值对的顺序,每个键值对既位于哈希表中,也位于这个双向链表中

LinkedHashMap 支持两种顺序,一种是插入顺序,另外一种是访问顺序

插入顺序容易理解,先添加的在前面,后添加的在后面,修改操作不影响顺序。

访问顺序是什么意思呢?所谓访问是指 get/put 操作,对一个键执行 get/put 操作后,其对应的键值对会移到链表末尾,所以,最末尾的是最近访问的,最开始的最久没被访问的,这种顺序就是访问顺序。

LinkedHashMap 有五个构造方法,其中四个都是按插入顺序,如下所示:

public LinkedHashMap()
public LinkedHashMap(int initialCapacity)
public LinkedHashMap(int initialCapacity, float loadFactor)
public LinkedHashMap(Map<? extends K, ? extends V> m)

只有一个构造方法,可以指定按访问顺序,如下所示:

public LinkedHashMap(int initialCapacity,
                     float loadFactor,
                     boolean accessOrder)

其中参数 accessOrder 就是用来指定是否按访问顺序,如果为 true,就是访问顺序。

下面,我们通过一些简单的例子来看下。

10.6.1.1 按插入有序

默认情况下,LinkedHashMap 是按插入有序的,我们来看代码:

Map<String,Integer> seqMap = new LinkedHashMap<>();

seqMap.put("c", 100);
seqMap.put("d", 200);
seqMap.put("a", 500);
seqMap.put("d", 300);

for(Entry<String,Integer> entry : seqMap.entrySet()){
   
    System.out.println(entry.getKey()+" "+entry.getValue());
}

键是按照 “c”, “d”, “a” 的顺序插入的,修改 “d” 的值不会修改顺序,所以输出为:

c 100
d 300
a 500

什么时候希望保持插入顺序呢

Map 经常用来处理一些数据,其处理模式是,接受一些键值对作为输入,处理,然后输出,输出时希望保持原来的顺序。比如一个配置文件,其中有一些键值对形式的配置项,但其中有一些键是重复的,希望保留最后一个值,但还是按原来的键顺序输出,LinkedHashMap 就是一个合适的数据结构。

再比如,希望的数据模型可能就是一个 Map,但希望保持添加的顺序,比如一个购物车,键为购买项目,值为购买数量,按用户添加的顺序保存。

另外一种常见的场景是,希望 Map 能够按键有序,但在添加到 Map 前,键已经通过其他方式排好序了,这时,就没有必要使用 TreeMap 了,毕竟 TreeMap 的开销要大一些。比如,在从数据库查询数据放到内存时,可以使用 SQL 的 order by 语句让数据库对数据排序。

10.6.1.2 按访问有序

我们来看按访问有序的例子,代码如下:

Map<String,Integer> accessMap = new LinkedHashMap<>(16, 0.75f, true);

accessMap.put("c", 100);
accessMap.put("d", 200
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bm1998

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值