MST

星途 面试题库

面试题:Java中LinkedHashSet在对象缓存应用里如何保证元素顺序

在使用Java的LinkedHashSet进行对象缓存时,描述一下它是如何保证元素插入顺序或者访问顺序的?请结合LinkedHashSet的内部数据结构进行说明。
31.5万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. LinkedHashSet概述

LinkedHashSetHashSet的子类,它不仅继承了HashSet基于哈希表实现的快速查找特性,还额外维护了一个双向链表来记录元素的插入顺序或访问顺序。

2. 保证插入顺序

  • 内部数据结构LinkedHashSet内部使用哈希表(本质是HashMap)来存储元素,保证元素的唯一性,同时使用双向链表来维护元素的插入顺序。双向链表的节点类型为LinkedHashSet.Entry,它继承自HashMap.Node,除了包含哈希表节点的基本属性(如hashkeyvaluenext)外,还额外包含两个属性beforeafter,用于双向链表的链接。
  • 插入过程:当调用add方法插入元素时,首先会调用HashMapput方法将元素插入到哈希表中。同时,LinkedHashSet会将新插入的元素添加到双向链表的尾部。这样,双向链表中节点的顺序就是元素的插入顺序。当遍历LinkedHashSet时,会按照双向链表的顺序依次访问元素,从而保证了插入顺序。

3. 保证访问顺序

  • 构造函数参数LinkedHashSet有一个构造函数LinkedHashSet(int initialCapacity, float loadFactor, boolean accessOrder),当accessOrdertrue时,LinkedHashSet会按照访问顺序维护元素。
  • 访问过程:当访问(如调用get方法获取元素,在LinkedHashSet中没有get方法,但在基于LinkedHashSet实现的LinkedHashMap中有类似逻辑)或修改(如重新插入已存在元素)一个元素时,如果accessOrdertrue,该元素会被移动到双向链表的尾部。这样,频繁访问的元素会逐渐移动到链表尾部,而链表头部的元素就是最久未被访问的元素。当遍历LinkedHashSet时,会按照从链表头部到尾部的顺序,即访问顺序来依次访问元素。