JDK 8 HashSet 源码解析

JDK8之HashSet 先上一张从网上找到的图片,这张图片概括了集合框架的结构。 上篇文章,对比说明了HashMap的实现以及在7和8两个版本中的区别,下面我们继续看下JDK8中HashSet的实现。 HashSet拥有两个成员变量 private transient HashMap map; // Dummy value to associate with an Object in the backi 阅读详情

【本文是为了梳理知识的总结性文章,总结了一些自认为相关的重要知识点,只为巩固记忆以及技术交流,忘批评指正。其中参考了很多前辈的文章,包括图片也是引用,如有冒犯,侵删。】

目录

0 存储结构

1 类定义

2 静态常量

3 属性

4 构造函数

默认构造方法

指定初始容量和负载因子的构造方法

指定初始容量的构造方法

使用LinkedHashMap的构造器

使用指定容器构造HashSet的构造器

5 常用方法

最佳实践


0 存储结构

从底层实现来看,HashSet 调用了HashMap来存储元素,不过之用到了Key,Value则用一个固定对象替代。由于Map中的key是不可重复的,这和Set不存在重复元素的特点刚好契合。使用HashMap也意味着不保证元素的顺序,允许使用 null 元素。

1 类定义

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

2 静态常量

由于HashSet只需要使用Key进行存储,因此Value存储的是一个虚拟值。

private static final Object PRESENT = new Object();

3 属性

底层调用HashMap对象进行存储和操作。

private transient HashMap<E,Object> map;

4 构造函数

主要是初始化HashMap,设置负载因子和初始容量。

默认构造方法

使用默认的HashMap构造方法,负载因子0.75,初始容量16。

    public HashSet() {
        map = new HashMap<>();
    }

指定初始容量和负载因子的构造方法

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

指定初始容量的构造方法

使用默认负载因子0.75

    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

使用LinkedHashMap的构造器

底层使用LinkedHashMap,并且是包私有的,只供LinkedHashMap使用。

    // dummy只用于区分构造方法
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

使用指定容器构造HashSet的构造器

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        // 使用Collection实现的Iterator迭代器,将集合c的元素一个个加入HashSet中
        addAll(c);
    }

5 常用方法

底层的方法都是通过调用HashMap完成的代码都很简单,详情可以查看HashMap的代码JDK 8 HashMap 源码解析。

   /** 
    * 返回set中元素的迭代器。调用hashMap的keySet来返回所有的key。 
    */  
   public Iterator<E> iterator() {  
       return map.keySet().iterator();  
   }  
 
   /** 
    * 返回set中的元素的数量。调用HashMap的size()方法数量。 
    */  
   public int size() {  
       return map.size();  
   }  
 
   /** 
    * 判断set是否为空。调用HashMap的isEmpty()进行判断。 
    */  
   public boolean isEmpty() {  
       return map.isEmpty();  
   }  
 
   /** 
    * 判断set包含指定元素。底层实际调用HashMap的containsKey来判断
    */  
   public boolean contains(Object o) {  
       return map.containsKey(o);  
   }  
 
   /** 
    * 添加元素。如果set已包含该元素,则该调用不更改set并返回false。 
    */  
   public boolean add(E e) {  
       return map.put(e, PRESENT)==null;  
   }  
 
   /** 
    * 移除set中的指定元素。 如果此set已包含该元素,则返回true。 
    * 调用HashMap的remove方法删除指定Entry。 
    */  
   public boolean remove(Object o) {  
       return map.remove(o)==PRESENT;  
   }  
 
   /** 
    * 清空set中移除所有元素。调用HashMap的clear方法清空。 
    */  
   public void clear() {  
       map.clear();  
   }  

最佳实践

  1. 由于底层使用HashMap实现的,所以最好预估使用场景所需的容量,并设置为初始值,防止多次扩容,影响性能(尤其在数据量大的时候);
  2. 存储自定义对象的时候,重写equals方法和hashCode方法,以免出错;
  3. HashMap不是线程安全的,多线程环境下可以使用Collections.synchronizedSet()进行包装;

 

 

HashSet源码解析(基于JDK1.8) HashSet是Java中经常被用到的集合,弄清它的底层实现,有利于我们更好地使用它,又是这句话….. 不过HashSet相对于其他集合框架简单了不少。 老规矩,还是先看看它的UML图: ①:实现了Serializable接口,表明它支持序列化。 ②:实现了Cloneable接口,表明它支持克隆,可以调用超类的clone()方法进行浅拷贝。 ③继承了AbstractSet抽象类... 阅读详情

相关推荐

对计算机专业来说学历真的重要吗?

我本科学校是渣渣二本,研究生学校是985,现在毕业五年,校招笔试、面试,社招面试参加了两年了,就我个人的经历来说下这个问题。 这篇文章很长,但绝对是精华,相信我,读完以后,你会知道学历不好的解决方案,记得帮我点赞哦。 先说结论,无论赞不赞同,它本质就是这样:对于技术类工作而言,学历五年以内非常重要,但有办法弥补。五年以后,不重要。 目录: 张雪峰讲述的事实 我看到的事实 为什么会这样 ...

启舰 55万+

JDK8系列:Set集合 之 HashSet源码分析

1、HashSet 简介 通过内部使用的 hashMap 保持元素的唯一性。 这个hashMap 的组成是 :key是set种的元素,但value全是PRESENT Set没有 get()方法,因为没有实际意义。Set中的元素没有顺序,根本不可能通过 index 取。但是Set有迭代器遍历元素 2、成员变量 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneab..

啦卡的博客 293

基于拟蒙特卡洛模拟法的随机潮流计算matlab程序

由式(4-11)可知,蒙特卡洛模拟法的计算量不受电力系统规模大小影响,因此该方法在一些复杂的电力系统中可以得到应用,包括处理电力系统中有多个间歇性新能源接入的问题,解决系统中多个节点之间相关性问题等等。本章在此基础上提出了基于拟蒙特卡洛模拟的随机潮流计算方法,并且对拟蒙特卡洛法中的拟随机数序列进行了改进,大大提高了随机潮流的计算效率。模拟法的具体思路如下:基于实际工程问题的求解需要,建立与之相对应的随机模拟过程和随机概率模型,使得它们的参数,包括概率分布或者数学期望,能够等于问题的实际解;

weixin_47365903的博客 1792

JAVA集合篇之HashSet底层源码(JDK8)

/至此,添加重复元素的逻辑处理结束,这里再分析一下再数组表中已经存在元素的时候的扩容机制resize(),分析见蓝色注释。// 将e指向p的下一个结点(p.next),判断p的下一个结点是否为null。else { // 计算出来的位置相同,但判断不是相同对象,也不是树结点,会进入该分支。//因此,当添加的元素已经有8个,继续添加的时候满足该if条件。// 因此,还要数组大小

qq_35099823的博客 2156

xctf攻防世界 MISC高手进阶区 low

1. 进入环境,下载附件 给出的一张bmp图片,没有其他信息 2. 问题分析 扔进binwalk中,没有发现有用信息 使用zsteg,没有有用信息 塞入StegSolve中,发现有点猫腻,如图: 有点二维码的感觉,emmm,需要像素处理,但不知道如何下手,参考网上的wp,发现是让使用lsb隐写,copy代码: from PIL import Image img = Image.open('./pic/low.bmp') img_tmp = img.copy() pix = img_tmp.load()

l8947943的博客 1万+

HAMi 核心模块与架构设计

HAMi 的架构设计是围绕 Kubernetes 生态系统构建的,通过扩展 Kubernetes 的调度能力和设备管理能力,为用户提供了高效、灵活的异构设备虚拟化和管理解决方案。

北斗云的博客 2552

JAVA集合之HashSet源码解析(JDK8)

文章目录前言源码解析HashSet类HashSet属性HashSet构造器HashSet主要方法总结 前言         我们在实际项目中通常会有这样的需求,将多个数据存储在一起,但是不希望得到重复的数据,那么HashSet将可以满足去重。 源码解析 HashSet类 HashSet是一个继承于AbstractSet...

qq_18581221的博客 3539

Word论文插入带有方括号序号的参考文献——尾注+交叉引用

文章目录1. 尾注功能2. 为参考文献的序号添加方括号3. 调整参考文献前的序号大小4. 重复引用同一参考文献5. 将交叉引用的序号改为带有方括号的上标序号格式6. 删除参考文献前的尾注横线 1. 尾注功能 首先使用尾注功能顺序插入参考文献,暂时不考虑方括号问题,具体操作如下: ① 将光标放在需要插入参考文献角标的地方 ② 在word菜单栏,“引用-脚注部分右下角箭头”(用来设置尾注格式) ③如...

Your_Raymond的博客 9万+

jdk8 源码之HashSet 和 LinkedHashMap

前面的博客中我们分析了HashMap的源码,这一篇我们说一下HashSet和LinkedHashMap的实现逻辑。他们其实都是基于HashMap来实现,因此把它们放在一起讲还是比较合适的。HashSet也被称为集合,但该容器中只能存储不重复的对象。LinkedHashMap在HashMap功能基础上,记录的对象的插入顺序。

灵小帝的博客 414

YOLOv8剪枝 l1剪枝测试精度仅掉0.8个点,速度提高10.7fps!

文章摘要: 本文提出了一种基于组归一化的重要性评分方法GroupNormImportance,用于神经网络剪枝中的通道选择。该方法支持多种变体,包括标准L1范数、组L1范数和BN缩放因子等计算方式。核心实现包括三个关键部分:1)支持p范数计算(默认为L2);2)提供7种组重要性归约方法(如均值、最大值等);3)提供8种归一化方案(包括标准化、高斯化、LAMP等)。该方法输入一个剪枝组,输出各通道的重要性分数,通过依赖图可实现结构化剪枝。实验对比图展示了剪枝前后的效果差异,验证了该方法的有效性。

FJN110的博客 397

【STM32项目】基于Stm32c8t6-镭射激光打印机的设计(完整工程资料源码)

随着打印技术的快速发展,镭射打印技术也开始得到越来越广泛的应用。这种技术可以被用于在木材、塑料、皮革、织物等各种材料上进行图形打印,并且通常比传统机器更快、更准确和更灵活。

嵌入式技术开发 7198

HashSet源码解析(JDK1.8)

HashSet源码解析(JDK1.8) 文章目录HashSet源码解析(JDK1.8)HashSet实现原理HashSet的属性HashSet的方法构造方法空参构造HashSet()HashSet(Collection<? extends E> c)HashSet(int initialCapacity, float loadFactor)HashSet(int initialCapacity)HashSet(int initialCapacity, float loadFactor, bool

qq_44709990的博客 955

SAP Gateway 中事务码 /IWFND/MAINT_SERVICE 的用法介绍

本文系统梳理了SAP Gateway中/IWFND/MAINT_SERVICE事务码的核心功能与运维实践。作为OData服务管理中樞,它支持服务注册激活、ICF节点配置、系统别名绑定、批量处理等关键操作。文章详解了服务目录、ICF节点、系统别名的配置要点,提供了批量激活、缓存清理、性能监控等实用技巧,并针对常见陷阱(如传输配置、删除残留)给出解决方案。通过制造业批量激活、零售业OAuth集成等案例,展示了事务码在企业级应用中的实际价值,为SAP Gateway运维提供了一套完整的治理清单。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 302

HashSet源码解析——基于JDK1.8

前言 HashSet 是一个不允许存储重复元素的集合,它的实现比较简单,只要理解了 HashMap,HashSet 就水到渠成了。当然了解HashMap可以参考我的这篇文章 1 常量介绍 //使用HashMap来实现Set的相关功能 private transient HashMap<E,Object> map; // 将假value与map中的对象关联 // Dumm...

nero_claudius的博客 268

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

JDK8 HashSet源码解析

前言 HashSet我们使用很多,但仅仅在使用的角度,用法很简单,现在分析原理 1. 总体概览 public class HashSet&lt;E&gt; extends AbstractSet&lt;E&gt; implements Set&lt;E&gt;, Cloneable, java.io.Serializable { static final long ...

fenglllle的博客 629

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

HashSet源码解析 --基于JDK1.8

文章目录结构属性构造器方法add: 结构 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { } HashSet继承自AbstractSet,实现了Set, Cloneable, java.io.Serializable接口。 属性 //序列化id static final long serialV

qq_41202539的博客 457

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

HashSet源码解析(JDK1.8)

在我们学过HashMap之后,再来看HashSet就很easy了。因为HashSet是基于HashMap是实现的。打开HashSet的源码,可以看到维护了一个HashMap一、成员变量//用来存储HashSet的元素 private transient HashMap&lt;E,Object&gt; map; //这个Object是用来填充HashMap的value的。 private stati...

yanghan1222的博客 195

HashSet、CopyOnWriteArraySet、ConcurrentSkipListSet源码解析(JDK1.8)

set源码解析HashSet源码解析HashSet简单使用的demoHashSet中的变量合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入...

狐言 358

JAVA集合源码解析 HashSet 探索(基于JDK1.8)

JDK1.8HashSet探索 本文所讨论的源码是基于JDK1.8展开的,由于篇幅有限,只讨论主要部分 JDK1.8HashSet探索 1.简介 2.探索 2.1类关系 2.2属性 2.3构造方法 2.4核心方法 3.总结 1.简介 HashSet 是不同步的,继承的 set 接口,所以里面的元素是不能重复的,无序的,允许包含值为null的元素,但最多只能有...

我在阴山下 665

JDK8集合类源码解析 - HashSet

HashSet 特点:不允许放入重复元素 查看源码,发现HashSet是基于HashMap来实现的,对HashMap做了一次“封装”。 private transient HashMap<E,Object> map; private static final Object PRESENT = new Object(); //map的value ...

weixin_30752377的博客 94

Java集合深入学习 - HashSet源码解析(基于jdk1.8)

HashSet。。。感觉就像是一个阉割版的HashMap。。 /** * 定义HashSet类 继承 AbstractSet 实现Set,Cloneable,Serializable */ public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { static final long serialVersionUID

luo_mu_hpu的博客 199

HashSet

HashSet源码解析(基于JDK1.8)_m0_37884977的博客-优快云博客_hashset源码

pubgNO1的博客 366

JDK1.8源码阅读记录HashSet类

JDK1.8源码阅读记录 JAVA.Util包 HashSet类 说明 public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable HashSet类继承了AbstractSet抽象类,实现了Set、Clonea...

weixin_43459704的博客 173

JDK 8 HashSet 源码详解(完整版带详细注释)

JDK 8 的 HashSet 是基于 HashMap 实现的集合类,所有元素作为 HashMap 的 key 存储,对应的 value 统一使用 PRESENT 对象占位。核心特性包括:默认初始容量 16,负载因子 0.75;通过 HashMap 实现基本操作(add/remove/contains 时间复杂度 O(1));支持序列化和克隆;迭代器返回元素的顺序无序。LinkedHashSet 继承 HashSet,通过 LinkedHashMap 保持插入顺序。源码实现包含构造方法、核心操作方法(add

csdn_tom_168的博客 659

Java CopyOnWriteArraySet源码深度解析

介绍了JDK1.8的CopyOnWriteArraySet的特性和源码实现!

终生学习践行者 2348
上一篇: JDK 8 LinkedList 源码解析
下一篇: 数据结构之红黑树Java实现
TaiSung
博客等级 码龄15年 49粉丝 132原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值