Java HashSet

HashSet 是一个基于 HashMap 实现的无序列表。
它不保证数据存储的顺序, 但是可以保证存储的数据是唯一不重复的, 同时支持存储 null。

如果再了解 HashMap 后, HashSet 是几个 Collection 实现中最容易理解的集合, 因为 HashSet 的所有操作都是借助于 HashMap 实现的。

HashSet 内部声明了一个 HashMap, 然后将数据存储在 HashMap 的 key 中, 所有的 value 直接设置为同一个 Object 对象, 借助 HashMap key 的唯一性间接的实现了 HashSet 的唯一性。

1 HashSet 中的几个重要属性

public class HashSet<E> {// 一个静态, 不可变的 Object 变量// 静态保证了唯一性, 整个应用就一个, 可以节省空间// 不可变, 进一步保正这个对象不会被任何线程修改private static final Object PRESENT = new Object();// HashSet 中存储数据的地方// 就是借助 HashMap 存储的, 存入 HashSet 的数据, 统一放到这个 HashMap 的 key 中, 这个 key 对应的 value 则统一为上面定义的静态 Objectprivate transient HashMap<E,Object> map;
}

2 HashSet 的构造方法

2.1 无参的构造函数

public HashSet() {// 为属性 map 赋值, 声明为 HashMapmap = new HashMap<>();
}

很简单, 创建一个 HashMap, 并赋值给自己存储数据的属性 HashMap<E,Object> map

2.2 指定容量的构造函数

public HashSet(int initialCapacity) {// 指定容量 map = new HashMap<>(initialCapacity);
}

同样, 直接创建一个指定容量的 HashMap, 然后赋值给自己存储数据的属性 HashMap<E,Object> map

2.3 指定容量和负载因子的构造函数

public HashSet(int initialCapacity, float loadFactor) {// 指定容量, 负载因子map = new HashMap<>(initialCapacity, loadFactor);
}

依旧是直接调用对应 HashMap 的方法, 创建出需要的 HashMap, 再赋值给自己的 HashMap<E,Object> map 属性

2.4 给定一个 Collection 的构造函数

public HashSet(Collection<? extends E> c) {// 创建一个 HashMap 赋值到自己的属性map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));// 添加全部addAll(c);
}// 将一个集合中的数据遍历添加到自己的 HashMap 中
public boolean addAll(Collection<? extends E> c) {boolean modified = false;// 依次遍历每一个元素for (E e : c)if (add(e))modified = true;return modified;
}// 向自己的 HashMap 添加数据
public boolean add(E e) {// 很简单的调用 HashMap 的 put 方法, key 值为需要存入的数据, value 为 声明好的静态变量 PRESENTreturn map.put(e, PRESENT)==null;
}

2.5 一个比较特殊的构造函数: 没有提供出去的构造函数

HashSet(int initialCapacity, float loadFactor, boolean dummy) {// dump 参数没有作用, 只是为了重载// 通过这个构造函数, 可以将 HashSet 默认的 map 实现变为 LinkedHashMap, 主要是给子类 LinkedHashSet 起使用, 达到有序的效果map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

3 HashSet 的操作方法

3.1 添加数据

public class HashSet<E> {// 单个添加元素public boolean add(E e) {// 直接调用 map 的 put 方法return map.put(e, PRESENT)==null;}
}

3.2 其他的添加方法

public class HashSet<E> {// 直接添加一个集合public boolean addAll(Collection<? extends E> c) {boolean modified = false;for (E e : c)// 遍历所有的元素, 调用自身的 add 方法if (add(e))modified = true;return modified;}
}

3.3 删除数据

public class HashSet<E> {public boolean remove(Object o) {// 同样是调用 map 的 remove 方法return map.remove(o)==PRESENT;}
}

同样的可以通过 removeAll 直接清空 HashSet 的数据

3.4 查询数据

Set 比较特殊, 没有提供直接获取值的方法 get 方法。
因为没必要, 如果你现在已经有一个数据 a, Set.get(a), 返回结果想要什么?
如果只是单纯的是想判断对象是否存在,可以通过 contain 方法进行判断。

4 HashSet 的补充

  1. 因为 HashSet 是通过 HashMap 实现的, HashMap 的 key 可以存 null, 但是只能存一个, 所以 HashSet 支持存 null, 同时只能存一个
  2. 因为 HashMap 是非线程安全的,所以 HashSet 也是线程非安全的。
  3. HashSet 也是自定义了序列化方法
  4. HashSet 内部没有提供自己的迭代器, 他内部是通过 HashMap 的 key 迭代器实现的
  5. HashMap 支持 fail-fast 机制, 理所当然的 HashSet 也是。
  6. HashSet 的数据是无序的, 如果需要使用有序的 Set, 可以使用 LinkedHashSet, 内部是借助 LinkedHashMap 实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/178899.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【并发编程】ConcurrentHashMap底层结构和原理

&#x1f4eb;作者简介&#xff1a;小明Java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

【Python百宝箱】密码学之美:Python安全性实战手册

前言 在当今数字化时代&#xff0c;数据安全和隐私保护是至关重要的。密码学作为信息安全的基石&#xff0c;为我们提供了许多关键的工具和算法&#xff0c;用于加密、解密、数据完整性验证和密码管理。Python生态系统中有多个强大的密码学库&#xff0c;本文将深入探讨其中一…

wmvcore.dll丢失怎么办?解决电脑出现wmvcore.dll丢失问题5个方法

wmvcore.dll缺失5个解决方法与wmvcore.dll丢失原因及文件介绍 引言&#xff1a; 在日常使用电脑的过程中&#xff0c;我们可能会遇到一些错误提示&#xff0c;其中之一就是wmvcore.dll缺失。wmvcore.dll是Windows Media Video编码解码相关动态链接库文件之一&#xff0c;它对…

Linux 项目自动化构建工具:make/makefile

什么是 make make 是一个命令&#xff0c;他会在源文件的当前目录下寻找 makefile 或者 Makefile 文件执行这个文件中的代码。 makefile 文件的编写 我们先来见见猪跑&#xff0c;看看 make 怎么用的&#xff1a; 下面是 makefile 文件的内容&#xff1a; 这是 test.c 中的…

WPF创建进度条

使用wpf做一个原生的进度条&#xff0c;进度条上面有值&#xff0c;先看效果。 功能就是点击按钮&#xff0c;后台处理数据&#xff0c;前台显示处理数据的变化&#xff0c;当然还可以对进度条进行美化和关闭的操作&#xff0c;等待后台处理完毕数据&#xff0c;然后自动关闭。…

Python入职某新员工大量使用Lambda表达式,却被老员工喷是屎山

Python中Lambda表达式是一种简洁而强大的特性,其在开发中的使用优缺点明显,需要根据具体场景权衡取舍。 Lambda表达式的优点之一是它的紧凑语法,适用于一些短小而简单的函数。这种形式使得代码更为精炼,特别在一些函数式编程场景中,Lambda表达式可以提高代码的表达力。此外…

DMX512协议及对接口电路的分析

1、DMX512协议简介 DMX 是Digital MultipleX 的缩写&#xff0c;意为多路数字传输(具有512条信息的数字多路复用”)。DMX512控制协议是美国舞台灯光协会(usITT)于1990年发布的灯光控制器与灯具设备进行数据传输的工业标准&#xff0c;全称是USITTDMX512(1990); DMX512 在其物理…

福州大学《嵌入式系统综合设计》 实验八:FFMPEG视频编码

一、实验目的 掌握使用算能平台进行视频编码的流程&#xff0c;包括开发主机环境与云平台的配置&#xff0c;视频编码程序的编写与理解&#xff0c;代码的编译、运行以及学习使用码流分析工具分析视频压缩码流等。 二、实验内容 搭建实验开发环境&#xff0c;编译并运行编码…

设计模式在实际业务中应用 - 模版方法

1. 业务背景 作者在工作中主要主导 A 业务线的系统建设&#xff0c;A 业务线主要是零售场景酒水的售卖与即时配送服务。为了方便运营在自研系统中对多平台商品进行管理而开发的三方平台商品管理功能&#xff0c;本次介绍的模版方法模式则是在该功能开发过程中的落地实践。 2.…

vue前端前端页面权限验证方式

在Vue应用中使用Vuex&#xff08;Vue的状态管理库&#xff09;来存储用户组&#xff08;user group&#xff09;和角色&#xff08;roles&#xff09;信息是一种合理的做法&#xff0c;特别是在涉及到权限管理和用户身份的情况下。Vuex提供了一个集中式的状态管理方案&#xff…

CeresPCL 曲线拟合之三次多项式

文章目录 一、简介2.1 实现步骤二、实现代码三、实现效果参考资料一、简介 2.1 实现步骤 (1)构建代价函数。假设我们得到了一组数据,也知晓该数据是用曲线方程: y = a x 3 + b x 2 + c x +

Spring Boot 3.2.0 虚拟线程初体验 (部分装配解析)

写在前面 spring boot 3 已经提供了对虚拟线程的支持。 虚拟线程和平台线程主要区别在于&#xff0c;虚拟线程在运行周期内不依赖操作系统线程&#xff1a;它们与硬件脱钩&#xff0c;因此被称为 “虚拟”。这种解耦是由 JVM 提供的抽象层赋予的。 虚拟线程的运行成本远低于平…

qt QString常用方法

1. QString 尾部拼接,尾部插入字符.调用append()函数.同时,QString字符串直接用加号 也可以进行拼接. QString s "我的女神";s s "刘亦菲";s "最近可好?";s.append("你跑哪儿去了?");//拼接结果: 我的女神刘亦菲最近可好?你跑…

Java中的mysql——面试题+答案(数据库设计)——第25期

MySQL数据库的设计是关系数据库设计的一个重要方面&#xff0c;涉及表的结构、索引、外键关系等。 需求分析&#xff1a; 在设计数据库之前&#xff0c;确保充分了解业务需求和数据关系&#xff0c;分析系统需要存储的数据以及各数据之间的关系。 规范化&#xff1a; 使用数据…

组合设计模式

package com.jmj.pattern.combination;/*** 菜单组件&#xff0c;属于抽象根节点*/ public abstract class MenuComponent {//菜单组件的名称protected String name;//菜单组件的层级protected int level;//添加子菜单public void add(MenuComponent menuComponent) {throw new…

12.Spring源码解析-其它标签解析

容易看出&#xff0c;Spring其实使用了一个Map了保存其映射关系&#xff0c;key就是命名空间的uri&#xff0c;value是NamespaceHandler对象或是Class完整名&#xff0c;如果发现是类名&#xff0c;那么用反射的方法进行初始化&#xff0c;如果是NamespaceHandler对象&#xff…

计算虚拟化之CPU——qemu解析

解析 qemu 的命令行&#xff0c;qemu 的命令行解析&#xff0c;就是下面这样一长串。 qemu_add_opts(&qemu_drive_opts);qemu_add_opts(&qemu_chardev_opts);qemu_add_opts(&qemu_device_opts);qemu_add_opts(&qemu_netdev_opts);qemu_add_opts(&qemu_nic_…

C语言枚举的作用是什么?

我在知乎上看到这个问题&#xff0c;一开始&#xff0c;也有一些疑惑&#xff0c;后面查了一些资料&#xff0c;对于这个问题&#xff0c;简单的说一下我的看法。 枚举有多大 枚举类型到底有多大&#xff0c;占多少空间呢&#xff1f;这个要具体情况具体分析&#xff0c;编译器…

Java中的mysql——面试题+答案(基本题)——第21期

在Java中使用MySQL是一个常见的面试话题。 什么是JDBC&#xff1f; 答案&#xff1a; Java数据库连接&#xff08;JDBC&#xff09;是Java编程语言中用于与数据库建立连接、执行SQL语句和处理结果的API。它提供了一种标准的接口&#xff0c;使得Java应用程序能够与各种关系型数…

【shell】多行重定向与免交互expect与ssh、scp的结合使用

目录 一、多行重定向 举例1&#xff1a;使用read命令接收用户的输入值会有交互过程 举例2&#xff1a;设置变量的值 举例3&#xff1a;创建用户密码 举例4&#xff1a;使用多行重定向写入文件中&#xff08;以repo文件举例&#xff09; 举例5&#xff1a;变量设定 二、免…