java源码 -- LinkedHashSet
问题
(1)LinkedHashSet的底层使用什么存储元素?
(2)LinkedHashSet与HashSet有什么不同?
(3)LinkedHashSet是有序的吗?
(4)LinkedHashSet支持按元素访问顺序排序吗?
源码分析
LinkedHashSet继承自HashSet,让我们直接上源码来看看它们有什么不同。
package java.util; // LinkedHashSet继承自HashSet
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable { private static final long serialVersionUID = -2851667679971038690L; // 传入容量和装载因子
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
} // 只传入容量, 装载因子默认为0.75
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
} // 使用默认容量16, 默认装载因子0.75
public LinkedHashSet() {
super(16, .75f, true);
} // 将集合c中的所有元素添加到LinkedHashSet中
// 好奇怪, 这里计算容量的方式又变了
// HashSet中使用的是Math.max((int) (c.size()/.75f) + 1, 16)
// 这一点有点不得其解, 是作者偷懒?
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
} // 可分割的迭代器, 主要用于多线程并行迭代处理时使用
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT | Spliterator.ORDERED);
}
}
完了,结束了,就这么多,这是全部源码了,真的。
可以看到,LinkedHashSet中一共提供了5个方法,其中4个是构造方法,还有一个是迭代器。
4个构造方法都是调用父类的super(initialCapacity, loadFactor, true);
这个方法。
这个方法长什么样呢?
还记得我们上一节说过一个不是public的构造方法吗?就是它。
// HashSet的构造方法
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
如上所示,这个构造方法里面使用了LinkedHashMap来初始化HashSet中的map。
现在这个逻辑应该很清晰了,LinkedHashSet继承自HashSet,它的添加、删除、查询等方法都是直接用的HashSet的,唯一的不同就是它使用LinkedHashMap存储元素。
那么,开篇那几个问题是否能回答了呢?
总结
(1)LinkedHashSet的底层使用LinkedHashMap存储元素。
(2)LinkedHashSet是有序的,它是按照插入的顺序排序的。
彩蛋
通过上面的学习,我们知道LinkedHashSet底层使用LinkedHashMap存储元素,而LinkedHashMap是支持按元素访问顺序遍历元素的,也就是可以用来实现LRU的,最近最少使用算法。
那么,LinkedHashSet支持按元素访问顺序排序吗?
让我们一起来分析下。
首先,LinkedHashSet所有的构造方法都是调用HashSet的同一个构造方法,如下:
// HashSet的构造方法
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
然后,通过调用LinkedHashMap的构造方法初始化map,如下所示:
public LinkedHashMap(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
accessOrder = false;
}
可以看到,这里把accessOrder写死为false了。
所以,LinkedHashSet是不支持按访问顺序对元素排序的,只能按插入顺序排序。
参考:https://www.cnblogs.com/tong-yuan/p/LinkedHashSet.html
java源码 -- LinkedHashSet的更多相关文章
- 【java集合框架源码剖析系列】java源码剖析之HashSet
注:博主java集合框架源码剖析系列的源码全部基于JDK1.8.0版本.本博客将从源码角度带领大家学习关于HashSet的知识. 一HashSet的定义: public class HashSet&l ...
- 如何阅读Java源码 阅读java的真实体会
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动. 源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比 ...
- Android反编译(一)之反编译JAVA源码
Android反编译(一) 之反编译JAVA源码 [目录] 1.工具 2.反编译步骤 3.实例 4.装X技巧 1.工具 1).dex反编译JAR工具 dex2jar http://code.go ...
- 如何阅读Java源码
刚才在论坛不经意间,看到有关源码阅读的帖子.回想自己前几年,阅读源码那种兴奋和成就感(1),不禁又有一种激动.源码阅读,我觉得最核心有三点:技术基础+强烈的求知欲+耐心. 说到技术基础,我打个比方吧, ...
- Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库
http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...
- Programming a Spider in Java 源码帖
Programming a Spider in Java 源码帖 Listing 1: Finding the bad links (CheckLinks.java) import java.awt. ...
- 解密随机数生成器(二)——从java源码看线性同余算法
Random Java中的Random类生成的是伪随机数,使用的是48-bit的种子,然后调用一个linear congruential formula线性同余方程(Donald Knuth的编程艺术 ...
- Java--Eclipse关联Java源码
打开Eclipse,Window->Preferences->Java 点Edit按钮后弹出: 点Source Attachment后弹出: 选择Java安装路径下的src.zip文件即可 ...
- 使用JDT.AST解析java源码
在做java源码的静态代码审计时,最基础的就是对java文件进行解析,从而获取到此java文件的相关信息: 在java文件中所存在的东西很多,很复杂,难以用相关的正则表达式去一一匹配.但是,eclip ...
随机推荐
- 数据结构实验之查找四:二分查找(SDUT 3376)
#include <stdio.h> #include <string.h> #include <stdlib.h> int a[1000005]; int fin ...
- 【模板】杜教筛(Sum)
传送门 Description 给定一个正整数\(N(N\le2^{31}-1)\) 求 \[ans1=\sum_{i=1}^n \varphi(i)\] \[ans_2=\sum_{i=1}^n \ ...
- WPF_AutoCompleteBox智能提示_Xml读写
效果图 1.需要引用的DLL 2. Window.xaml <Window x:Class="自己的命名空间" xmlns="http://schemas.micr ...
- Kettle中ETL的效率优化
ETL效率优化 开启数据库日志记录及性能监控 如果我们想要优化一个ETL(KTR或者KJB)的性能,我们首先需要知道的就是它的瓶颈在哪里.而这些信息一般只能在ETL运行的步骤度量中看到,并且是不会持久 ...
- windows 家庭版 开启Hyper-V
windows 家庭版无法开启Hyper-V ,建议升级成专业版.
- Alpha项目冲刺! Day1-领航
各个成员在 Alpha 阶段认领的任务 成员 任务 任务时长 林恩 项目进度签到代码审核与签入撰写博客协调组内合作 50 寇永明 美工和部分后台编写 30 杨长元 安卓端搭建 45 胡彤 服务器框架搭 ...
- vscode远程代码同步
参考资料: https://blog.csdn.net/u012560340/article/details/83030680 https://github.com/liximomo/vscode-s ...
- python 设计模式之享元(Flyweight)模式
#写在前面 这个设计模式理解起来很容易.百度百科上说的有点绕口. #享元模式的定义 运用共享技术来有効地支持大量细粒度对象的复用. 它通过共享已经存在的对橡大幅度减少需要创建的对象数量.避免大量相似类 ...
- AtomicInteger的CAS算法浅析
之前浅析过自旋锁(自旋锁浅析),我们知道它的实现原理就是CAS算法.CAS(Compare and Swap)即比较并交换,作为著名的无锁算法,它也是乐观锁的实现方式之一.JDK并发包里也有许多代码中 ...
- Scala 踩坑系列
scala List scala list 如果使用 list(i)的形式进行遍历,如果list数据太多,每次遍历耗时会很久. 因为有一个 head tail 的概念 . 和java的List根据角标 ...