深入理解Java HashSet类及其实现原理

哈喽,各位小伙伴们,你们好呀,我是喵手。运营社区:C站/掘金/腾讯云;欢迎大家常来逛逛

  今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流,互相学习,一个人虽可以走的更快,但一群人可以走的更远。

  我是一名后端开发爱好者,工作日常接触到最多的就是Java语言啦,所以我都尽量抽业余时间把自己所学到所会的,通过文章的形式进行输出,希望以这种方式帮助到更多的初学者或者想入门的小伙伴们,同时也能对自己的技术进行沉淀,加以复盘,查缺补漏。

小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对作者我写作道路上最好的鼓励与支持!

前言

  在Java开发中,集合框架是非常重要的一部分,集合框架为Java提供了一种方式来管理和组织数据。其中HashSet是集合框架中的一种重要实现方式,它提供了一种存储集合元素的无序且唯一的方式。

摘要

  本文将介绍HashSet的基本概念,功能特点,使用方法,以及优缺点分析和应用场景案例。通过本文的学习,读者将会具备使用HashSet的能力,同时了解HashSet的优势和限制。

HashSet

简介

  HashSet是Java集合框架中的一种Set接口的实现。与List集合不同,Set集合中没有重复元素,HashSet提供了一种高效的无序存储方式,可以存储不同类型的数据,包括数字,字符串,对象和集合等。

  HashSet使用哈希表作为存储数据的方式,底层实现是HashMap,每个元素在HashSet中都有一个对应的Key和Value。当添加一个元素到HashSet中时,HashSet会根据元素的hashCode()方法值计算出对应的Key,再将元素加入到HashMap中。如果已存在相同Key的元素则会被覆盖,因此HashSet中不会存在重复元素。

  HashSet的基本操作包括添加元素、删除元素、判断元素是否存在、遍历元素等。

源代码解析

以下是HashSet的源代码解析:

public class HashSet<E> extends AbstractSet<E>implements Set<E>, Cloneable, Serializable
{// 底层实现为HashMapprivate transient HashMap<E,Object> map;// Dummy value to associate with an Object in the backing Mapprivate static final Object PRESENT = new Object();// 构造函数public HashSet() {map = new HashMap<>();}public boolean add(E e) {return map.put(e, PRESENT)==null;}public boolean remove(Object o) {return map.remove(o)==PRESENT;}public boolean contains(Object o) {return map.containsKey(o);}public void clear() {map.clear();}public int size() {return map.size();}public Iterator<E> iterator() {return map.keySet().iterator();}public Object clone() {try {HashSet<E> newSet = (HashSet<E>)super.clone();newSet.map = (HashMap<E,Object>)map.clone();return newSet;} catch (CloneNotSupportedException e) {throw new InternalError(e);}}private void writeObject(ObjectOutputStream s)throws IOException {s.defaultWriteObject();s.writeInt(map.capacity());s.writeFloat(map.loadFactor());s.writeInt(map.size());for (E e : map.keySet())s.writeObject(e);}private void readObject(ObjectInputStream s)throws IOException, ClassNotFoundException {s.defaultReadObject();int capacity = s.readInt();if (capacity < 0) {throw new InvalidObjectException("Illegal capacity: " +capacity);}float loadFactor = s.readFloat();if (loadFactor <= 0 || Float.isNaN(loadFactor)) {throw new InvalidObjectException("Illegal load factor: " +loadFactor);}int size = s.readInt();if (size < 0) {throw new InvalidObjectException("Illegal size: " +size);}map = new HashMap<>(capacity, loadFactor);for (int i=0; i<size; i++) {E e = (E) s.readObject();map.put(e, PRESENT);}}
}

如下是部分源码截图:

在这里插入图片描述

应用场景案例

HashSet的应用场景比较广泛,例如:

  • 数据去重:通过将数据存储在HashSet中,可以快速去除重复的数据。
  • 缓存管理:可以使用HashSet来存储缓存对象,以提高缓存查找效率。
  • 数据去重:通过将数据存储在HashSet中,可以快速去除重复的数据。

优缺点分析

HashSet的优点有:

  • 存储快速:HashSet使用哈希表作为底层存储结构,可以快速存储和查找元素。
  • 去重:HashSet中不会存在重复元素,可以用于数据去重。
  • 线程不安全:HashSet是线程不安全的,不适合在多线程环境中使用。

HashSet的缺点有:

  • 无序性:HashSet中的元素是无序的,不能按照特定的顺序进行操作。

类代码方法介绍

以下是HashSet类的常用方法介绍:

  • add(E e):将元素添加到HashSet中。
  • remove(Object o):将元素从HashSet中删除。
  • contains(Object o):判断元素是否存在于HashSet中。
  • clear():清空HashSet中的所有元素。
  • size():返回HashSet中元素的数量。
  • iterator():返回一个迭代器,可以遍历HashSet中的所有元素。

测试用例

以下是使用HashSet的测试用例:

测试代码演示

package com.example.javase.collection;import java.util.HashSet;/*** @Author ms* @Date 2023-10-21 21:05*/
public class HashSetTest {public static void main(String[] args) {HashSet<String> set = new HashSet<>();System.out.println(set.add("Hello"));System.out.println(set.add("World"));System.out.println(set.add("Hello"));System.out.println(set.remove("Hello"));System.out.println(set.remove("Hello"));System.out.println(set.contains("Hello"));System.out.println(set.contains("World"));set.clear();System.out.println(set.size());set.add("Hello");set.add("World");System.out.println(set.size());StringBuilder sb = new StringBuilder();for (String s : set) {sb.append(s);}System.out.println(sb.toString());}
}

测试结果

  根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。

在这里插入图片描述

测试代码分析

该代码演示了 HashSet 的基本用法。

  首先在 main 方法中创建一个空的 HashSet 对象 set,并向其中添加两个字符串 “Hello” 和 “World”。添加第一个元素 “Hello” 时返回 true,添加第二个元素 “World” 时返回 true,再添加第一个元素 “Hello” 时返回 false,因为 HashSet 不允许添加重复元素。

  接着,使用 remove 方法尝试删除元素 “Hello”,第一次删除成功并返回 true,第二次删除失败并返回 false,因为元素 “Hello” 已经被删除了。

  contains 方法用来判断元素是否存在于 HashSet 中,第一次查询元素 “Hello” 时返回 false,因为元素已经被删除,第二次查询元素 “World” 时返回 true,因为元素仍然存在。

  clear 方法将 HashSet 中的所有元素清空,使其变为空集合,因此调用 set.size() 方法返回 0。

  set.add 方法可以用于添加元素,再次添加元素 “Hello” 和 “World” 之后调用 set.size() 方法返回 2。

  最后使用 for-each 循环遍历 HashSet 中的元素,将每个元素拼接在一起后输出。因为 HashSet 是无序的,因此输出的字符串也是无序的。

全文小结

  本文介绍了HashSet的基本概念,功能特点,使用方法,以及优缺点分析和应用场景案例。HashSet是Java集合框架中的一种重要实现方式,提供了一种高效的无序存储方式,可以用于数据去重、缓存管理等场景。同时,HashSet是线程不安全的,需要注意使用。

总结

  HashSet是Java集合框架中的一种重要实现方式,具有存储快速、去重等优点,同时也存在一些缺点,例如无序性和线程不安全性。在实际的开发中,需要充分考虑应用场景和需求,选择合适的集合实现方式。

… …

文末

好啦,以上就是我这期的全部内容,如果有任何疑问,欢迎下方留言哦,咱们下期见。

… …

学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!

wished for you successed !!!


⭐️若喜欢我,就请关注我叭。

⭐️若对您有用,就请点赞叭。

⭐️若有疑问,就请评论留言告诉我叭。

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

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

相关文章

Java中什么是多态?多态的实现原理是什么?多态在Java中的意思实现方式是什么?多态在框架设计中有什么作用应用场景?

什么是多态&#xff1f; 多态是面向对象编程中的一个重要概念&#xff0c;它允许不同类的对象对同一消息做出响应。在 Java中&#xff0c;多态通常体现为子类对象可以替代父类对象的特性。这意味着你可以使用父类的引用来引用子类的对象。 多态的实现原理&#xff1a; 多态的…

如何在 CentOS 上安装并配置 Redis

如何在 CentOS 上安装并配置 Redis 但是太阳&#xff0c;他每时每刻都是夕阳也都是旭日。当他熄灭着走下山去收尽苍凉残照之际&#xff0c;正是他在另一面燃烧着爬上山巅散烈烈朝晖之时。 ——史铁生 环境准备 本教程将在 CentOS 7 或 CentOS 8 上进行。确保你的系统已更新到最…

Channel实现Flutter与原生平台之间的双向通信

文章目录 &#xff08;一&#xff09;通过MessageChannel实现Flutter与原生平台之间的双向通信Flutter端实现MessageChannel通信步骤&#xff1a;Android端实现MessageChannel通信步骤&#xff1a; &#xff08;二&#xff09;通过MethodChannel实现Flutter与原生平台之间的双向…

uniapp/微信小程序实现加入购物车点击添加飞到购物车动画

1、预期效果 2、实现思路 每次点击添加按钮时&#xff0c;往该按钮上方添加一个悬浮元素&#xff0c;通过位移动画将元素移到目标位置。 1. 为每个点击元素设置不同的class&#xff0c;才能通过uni.createSelectorQuery来获取每个元素的节点信息&#xff1b; 2. 添加一个与…

c++:(map和set的底层简单版本,红黑树和AVL树的基础) 二叉搜索树(BST)底层和模拟实现

文章目录 二叉搜索树的概念二叉搜索树的操作二叉搜索树的查找find 二叉搜索树的模拟实现构造节点insertfinderase(细节巨多,面试可能会考)a.叶子节点b.有一个孩子左孩子右孩子 c.有两个孩子注意: erase代码 中序遍历 二叉搜索树的应用k模型k模型模拟实现的总代码 k-value模型k-…

7-Zip命令行调用命令收集(20个)

列出压缩文件的内容: 7z l archive.7z 解压压缩文件到当前目录: 7z x archive.7z 解压压缩文件到指定目录: 7z x archive.7z -o"C:\path\to\extract" 创建新的压缩文件 (添加到archive.7z): 7z a archive.7z file_to_compress 创建包含多个文件的压缩文件: 7z a arc…

【JVM】了解JVM规范中的虚拟机结构

目录 JVM规范的主要内容 1&#xff09;字节码指令集(相当于中央处理器CPU) JVM指令分类 2&#xff09;Class文件的格式 3&#xff09;数据类型和值 4&#xff09;运行时数据区 5&#xff09;栈帧 6&#xff09;特殊方法 7&#xff09;类库 JVM规范的主要内容 1&#…

Vue3+ElementPlus+TS开发业务功能的问题汇总(持续更新)

1.开发表单弹框功能时遇到两个问题&#xff1a;加入了校验规则后&#xff0c;无论下拉框是否选择数据下面的红色提示都会触发显示不会自动隐藏 &#xff1b; 另外&#xff0c;新增的功能在提交后数据无法重置&#xff0c;这种在修改时可能会出现&#xff0c;但新增正常情况是不…

走进C++:C到C++的过渡

目录 什么是C呢&#xff1f; C的发展史 多了一些吃前来很香的“语法糖”。 语法糖一&#xff1a;命名空间 命名空间有个强大的功能 如何使用 语法糖二&#xff1a;缺省参数 语法糖三&#xff1a;函数重载 语法糖四&#xff1a;引用 引用传参 引用返回 引用和…

【ZZULIOJ】1100: 求组合数(函数专题)(Java)

目录 题目描述 输入 输出 样例输入 Copy 样例输出 Copy 提示 code 题目描述 马上要举办新生程序设计竞赛了&#xff0c;与以往不同的是&#xff0c;本次比赛以班为单位&#xff0c;为了全面衡量一个班级的整体水平&#xff0c;要求从一个班的m位同学中任选k位同学代表本…

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制(2)

Android GPU渲染SurfaceFlinger合成RenderThread的dequeueBuffer/queueBuffer与fence机制&#xff08;2&#xff09; 计算fps帧率 用 adb shell dumpsys SurfaceFlinger --list 查询当前的SurfaceView&#xff0c;然后有好多行&#xff0c;再把要查询的行内容完整的传给 ad…

算法训练Day35 | ● 343. 整数拆分 ● 96.不同的二叉搜索树

343. 整数拆分 class Solution { public:int integerBreak(int n) {vector<int> dp(n1, 0);dp[2] 1;for(int i3; i<n1; i){for(int j 1; j<i/2; j){dp[i] max(dp[i], max(j*(i-j), j*dp[i-j]));}}return dp[n];} };参考文章&#xff1a;代码随想录-343. 整数拆分…

找不到msvcp140.dll无法执行代码的原因分析及修复方法

当用户在尝试运行某些应用程序或游戏时&#xff0c;可能会遇到系统弹出错误提示&#xff0c;显示“找不到msvcp140.dll无法执行代码”这一错误信息&#xff0c;它会导致程序无法正常启动。为了解决这个问题&#xff0c;我经过多次尝试和总结&#xff0c;找到了以下五种解决方法…

hadoop启动后没有namenode,datanode等解决方法

之前用的是虚拟机&#xff0c;在虚拟机上安装的hadoop&#xff0c;但是后来&#xff0c;电脑恢复出厂设置了&#xff0c;什么都重新开始。就在本地安装 Linux 子系统。 但是&#xff0c;有时候start-dfs.sh后&#xff0c;jps出现错误。 像这种拒绝连接 解决办法就是如下&…

我的创作纪念日1460天(4年)

机缘 作为一名技术爱好者&#xff0c;我最初成为创作者的初心源于对知识的渴望和对分享的热情。在参与多个实战项目的过程中&#xff0c;我积累了丰富的经验&#xff0c;这些经验不仅仅是代码和解决方案&#xff0c;更多的是对问题本质的理解和解决问题的思维方式。我意识到&a…

题目----力扣--移除链表元素

题目 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]示例 2&#xff1a; 输入&…

如何编译不同目录下的两个文件

1.直接编译 2.打包成动静态库进行链接

【智能优化算法】蜜獾优化算法(Honey Badger Algorithm,HBA)

蜜獾优化算法(Honey Badger Algorithm,HBA)是期刊“MATHEMATICS AND COMPUTERS IN SIMULATION”&#xff08;IF 3.6&#xff09;的2022年智能优化算法 01.引言 蜜獾优化算法(Honey Badger Algorithm,HBA)受蜜獾智能觅食行为的启发&#xff0c;从数学上发展出一种求解优化问题的…

【AMBA Bus ACE 总线 9 -- Non-cache IO device】

请阅读【AMBA Bus ACE 总线与Cache 专栏 】 欢迎学习:【嵌入式开发学习必备专栏】 文章目录 ACE Non-cache IO device非缓存I/O的工作原理在ARM中配置非缓存I/O示例场景Non-cache IO device Cache 访问ACE Non-cache IO device 在ARM架构中,ACE(AXI Coherency Extension,…

Flask 统一拦截器

import osfrom flask import Flask, request, sessionapp Flask(__name__) app.config[SECRET_KEY] os.urandom(24) # 生成24位的随机数种子&#xff0c;用于产生SESSION IDapp.route(/article/<int:article_id>) def test(article_id):"""路由地址参数…