一文搞懂HashSet类的底层实现原理

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

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

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

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

哈喽,各位小伙伴们,你们好呀,我是喵手。

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

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

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

前言

在 Java 中,集合是非常重要的一部分,它们可以简化代码编写,提高代码效率。Java 提供了许多集合类,其中 HashSet 类是一种非常常用的集合类。本文将对 HashSet 类进行详细介绍。

摘要

本文将对 Java 中的 HashSet 类进行介绍。首先,我们将介绍 HashSet 类的简介和源代码解析,然后提供一些实际应用场景案例。接着,我们将对 HashSet 类的优缺点进行分析,以及类代码方法的介绍。最后,我们会提供一些测试用例,全文小结和总结。

HashSet类

简介

HashSet 类是 Java 中的一种集合类,它继承了 AbstractSet 类,实现了 Set 接口。HashSet 类可以存储不同类型的数据,而且元素是无序的,元素的值可以为 null。在 HashSet 中,每个元素都必须是唯一的,并且它们是通过哈希表存储的。HashSet 类使用哈希算法来计算元素的索引位置。

HashSet 类有以下几个重要的方法:

  • add(Object obj):将元素添加到集合中。
  • clear():清空集合中的所有元素。
  • contains(Object obj):判断集合中是否包含指定的元素。
  • isEmpty():判断集合是否为空集。
  • remove(Object obj):从集合中删除指定的元素。
  • size():返回集合中的元素个数。

源代码解析

HashSet 类的源代码解析可以分为以下几个部分:

  • 成员变量
  • 构造方法
  • 类方法

成员变量

HashSet 类的成员变量如下:

// 存储元素的哈希表
private transient HashMap<E,Object> map;

// 存储创建 HashSet 时指定的默认大小(容量为16)和负载因子(0.75)
private static final Object PRESENT = new Object();

其中,map 变量存储了 HashSet 中的所有元素,这些元素是存储在一个哈希表中的。PRESENT 变量存储了一个 Object 对象,该对象在向 HashSet 中添加元素时使用。

在这里插入图片描述

构造方法

HashSet 类有多个构造方法:

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

public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

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

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

这些构造方法可以根据不同的情况创建 HashSet 对象。例如,第一个构造方法创建默认的 HashSet 对象,第二个构造方法创建一个包含指定 Collection 中所有元素的 HashSet 对象。

在这里插入图片描述

类方法

HashSet 类的常用方法如下:

// 添加元素
public boolean add(E e)

// 移除元素
public boolean remove(Object o)

// 返回集合的大小
public int size()

// 清空集合
public void clear()

// 判断集合是否包含指定元素
public boolean contains(Object o)

在这里插入图片描述

应用场景案例

HashSet 类在实际开发中具有广泛的应用场景。下面是一些常见的场景。

去除重复元素

HashSet 类中的元素是唯一的,因此可以用于去除 List 中的重复元素。

List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 2, 3, 4, 5, 4, 5));
Set<Integer> set = new HashSet<>(list);
list.clear();
list.addAll(set);
System.out.println(list); // [1, 2, 3, 4, 5]

判断集合是否包含指定元素

在 HashSet 中,可以使用 contains 方法来判断集合是否包含指定元素。

Set<Integer> set = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
System.out.println(set.contains(3)); // true
System.out.println(set.contains(6)); // false

去除空元素

HashSet 类中可以存储空元素,因此可以用于去除 List 中的空元素。

List<String> list = new ArrayList<>(Arrays.asList("a", "b", "", "c", ""));
Set<String> set = new HashSet<>(list);
set.remove("");
list.clear();
list.addAll(set);
System.out.println(list); // [a, b, c]

优缺点分析

优点

  • 可以存储不同类型的数据。
  • 元素是无序的。
  • 可以存储空元素。
  • 具有去重功能。

缺点

  • 查找元素的速度较慢。
  • 当元素较多时,可能会消耗较大的内存空间。

类代码方法介绍

除了上述常用方法之外,HashSet 类还有一些常见的方法。

// 返回集合中的所有元素
public Iterator<E> iterator()

// 将集合转换为数组
public <T> T[] toArray(T[] a)

// 返回集合的哈希码
public int hashCode()

// 比较两个集合是否相等
public boolean equals(Object o)

// 返回集合的字符串表示形式
public String toString()

// 添加元素
public boolean addAll(Collection<? extends E> c)

// 移除所有元素
public boolean removeAll(Collection<?> c)

// 保留集合中与指定集合的交集
public boolean retainAll(Collection<?> c)

// 判断集合是否包含指定集合中的所有元素
public boolean containsAll(Collection<?> c)

// 将集合转换为流
public Stream<E> stream()

// 将集合转换为并行流
public Stream<E> parallelStream()

拓展:

这是Java集合框架中Collection接口中的一些常用方法,分别实现了以下功能:

  1. iterator():返回集合中的所有元素的迭代器。
  2. toArray(T[] a):将集合转换为指定类型的数组。
  3. hashCode():返回集合的哈希码。
  4. equals(Object o):比较两个集合是否相等。
  5. toString():返回集合的字符串表示形式。
  6. addAll(Collection<? extends E> c):向集合中添加指定集合中的所有元素。
  7. removeAll(Collection<?> c):移除集合中与指定集合相同的元素。
  8. retainAll(Collection<?> c):移除集合中与指定集合不同的元素,保留与指定集合相同的元素。
  9. containsAll(Collection<?> c):判断集合是否包含指定集合中的所有元素。
  10. stream():将集合转换为流。
  11. parallelStream():将集合转换为并行流。

这些方法可以方便地对Java集合进行操作和处理。

测试用例

下面是一些针对 HashSet 类的测试用例。

测试代码演示

package com.example.javase.se.classes;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @Author ms
 * @Date 2023-11-02 22:36
 */
public class HashSetTest {

    public static void main(String[] args) {
        Set<Integer> set1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5));
        System.out.println("set1 size: " + set1.size());

        Set<Integer> set2 = new HashSet<>(Arrays.asList(1, 2, 3));
        System.out.println("set2 add(4): " + set2.add(4));
        System.out.println("set2 add(3): " + set2.add(3));

        Set<Integer> set3 = new HashSet<>(Arrays.asList(1, 2, 3));
        System.out.println("set3 remove(1): " + set3.remove(1));
        System.out.println("set3 remove(4): " + set3.remove(4));

        Set<Integer> set4 = new HashSet<>(Arrays.asList(1, 2, 3));
        System.out.println("set4 contains(2): " + set4.contains(2));
        System.out.println("set4 contains(4): " + set4.contains(4));

        Set<Integer> set5 = new HashSet<>(Arrays.asList(1, 2, 3));
        set5.clear();
        System.out.println("set5 isEmpty: " + set5.isEmpty());
    }
}

测试结果

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

在这里插入图片描述

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。

这是一个测试 HashSet 的程序,具体分析如下:

  1. 创建 HashSet 对象 set1,并添加元素 1、2、3、4、5,输出 set1 的大小。

  2. 创建 HashSet 对象 set2,并添加元素 1、2、3,尝试添加元素 4 和 3,输出添加结果。

  3. 创建 HashSet 对象 set3,并添加元素 1、2、3,尝试移除元素 1 和 4,输出移除结果。

  4. 创建 HashSet 对象 set4,并添加元素 1、2、3,尝试判断元素 2 和 4 是否存在,输出判断结果。

  5. 创建 HashSet 对象 set5,并添加元素 1、2、3,清空 set5,判断 set5 是否为空,输出判断结果。

以上操作都是使用 Set 接口中的方法进行的,具体来说:

  • 使用 HashSet 的构造方法,可以使用 Arrays.asList() 方法将数组转换成集合,从而快速添加元素。
  • add() 方法返回一个布尔值,表示添加元素的结果。当元素已存在时,不会再次添加,并且返回 false。
  • remove() 方法返回一个布尔值,表示移除元素的结果。当元素不存在时,不会进行移除,并且返回 false。
  • contains() 方法返回一个布尔值,表示集合中是否包含指定元素。
  • clear() 方法可以清空集合中的所有元素,使其成为空集合。
  • isEmpty() 方法可以判断集合是否为空,返回一个布尔值。

总体来说,HashSet 是一种基于哈希表实现的集合,具有快速添加、移除、判断元素是否存在的优势,同时不保证元素的顺序。

优点

  • 可以存储不同类型的数据。
  • 元素是无序的。
  • 可以存储空元素。
  • 具有去重功能。

缺点

  • 查找元素的速度较慢。
  • 当元素较多时,可能会消耗较大的内存空间。

小结

HashSet 类是 Java 中的一种集合类,它可用于存储不同类型的数据,元素是无序的,元素的值可以为 null。HashSet 类可以去除重复元素,具有去重功能。HashSet 类的优缺点如下:

总结

HashSet 类在 Java 中是一个非常实用的集合类。它可以用于存储不同类型的数据,并且具有去重功能。在实际开发中,我们可以使用 HashSet 类来去除 List 中的重复元素、判断集合中是否包含指定元素等等。但是需要注意的是,当元素较多时,可能会消耗较大的内存空间,因此在使用 HashSet 类时需要谨慎考虑。

… …

文末

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

… …

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

wished for you successed !!!


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

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

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

… …

文末

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

… …

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

wished for you successed !!!


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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud系列(27)--OpenFeign日志增强

前言&#xff1a;在上一章节中我们简单的介绍了如何去调节OprnFeign的连接超时时间&#xff0c;在OpenFeign的使用过程中可能需要对Feign接口的调用情况进行监控和输出&#xff0c;这时候就需要对OpenFeign进行日志增强处理&#xff0c;所以本节的内容即是关于OpenFeign的日志增…

第二证券炒股知识分享:吃银行股息划算吗?

银行股吃股息比较合算&#xff0c;它能超越银行存款利息&#xff0c;其间银行存款一年的利率大概在1.5%左右&#xff0c;而银行股票是a股商场一切板块傍边&#xff0c;分红率最高的&#xff0c;特别是大型商业银行股票&#xff0c;年年都坚持高分红&#xff0c;其股息会超越2%。…

Shell之(正则表达式)

目录 一、正则表达式的概括 常用选项 基础正则表达式 查看以xxx为开头 查看以xxx为结尾的文件内容 匹配单个或多个字符 匹配中括号里的内容 对子表达式进行多次或者限定次数的匹配 拓展正则表达式的基本用法 扩展元字符 匹配前面的字符或表达式至少1次&#xff0…

BUUCTF---misc---[MRCTF2020]ezmisc

1、附件下载后是一张图片 2、查看属性&#xff0c;winhex分析&#xff0c;没发现什么 3、在kali中binwalk和foremost也没找到什么信息 4、用stegsolve分析也没发现什么 5、这里几乎常见的misc方法都试过了&#xff0c;还是没有发现什么 6、回归到图片本身&#xff0c;想到的…

Nginx文件解析漏洞复现:CVE-2013-4547

漏洞原理 CVE-2013-4547漏洞是由于非法字符空格和截止符导致Nginx在解析URL时的有限状态机混乱&#xff0c;导致攻击者可以通过一个非编码空格绕过后缀名限制。假设服务器中存在文件1. jpg&#xff0c;则可以通过改包访问让服务器认为访问的为PHP文件。 漏洞复现 开启靶场 …

Python函数进阶:四大高阶函数、匿名函数、枚举、拉链与递归详解

系列文章目录 Python数据类型&#xff1a;编程新手的必修课深入探索Python字符串&#xff1a;技巧、方法与实战Python 函数基础详解Python正则表达式详解&#xff1a;掌握文本匹配的魔法Python文件操作宝典&#xff1a;一步步教你玩转文件读写Python面向对象基础与魔法方法详解…

sheng的学习笔记-docker部署Greenplum

目录 docker安装gp数据库 mac版本 搭建gp数据库 连接数据库 windows版本 搭建gp数据库 连接数据库 docker安装gp数据库 mac版本 搭建gp数据库 打开终端&#xff0c;输入代码&#xff0c;查看版本 ocker search greenplum docker pull projectairws/greenplum docker…

大模型618提前开战,永久免费意味着什么?

万万没想到&#xff0c;当我们在说经过上一年的百模大战&#xff0c;2024 年将成为大模型应用落地的关键一年&#xff0c;不承想&#xff0c;AI 大模型价格战疯狂席卷而来。 这场战役始于巨头。字节、阿里、百度、科大讯飞、腾讯先后官宣降价或免费&#xff0c;价格战所带来的…

风控指南:国内车险欺诈呈现四大趋势

目录 车险欺诈呈现内外勾结的团伙化 防范车险欺诈需要多重合作 保险企业需要提升反欺诈能力 监管部门需要加强协同合作 2024年4月11日&#xff0c;国家金融监督管理总局官网发布国家金融监督管理总局关于《反保险欺诈工作办法&#xff08;征求意见稿&#xff09;》公开征求意见…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-16讲 EPIT定时器

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

Lumines推出RGBL彩色混合LED

Luminus Devices倾心打造了一款崭新的4合1 RGBL&#xff08;红绿蓝绿石灰&#xff09;LED系列&#xff0c;专为舞台与建筑照明领域量身打造&#xff0c;满足对高显色指数&#xff08;CRI&#xff09;与高输出颜色混合的苛刻需求。这一创新之举&#xff0c;无疑是照明技术的一次…

【OpenGL实践10】关于几何着色器

目录 一、说明 二、几何着色器 2.1 设置 2.2 基本几何着色器 2.2.1 输入类型 2.2.2 输出类型 2.2.3 顶点输入 2.2.4 顶点输出 2.3 创建几何着色器 2.4 几何着色器和顶点属性 三、动态生成几何体 四、结论 练习 一、说明 几何着色器的应用比较高级&#xff0c;关于…

Postman使用技巧

Postman是一款广泛使用的API开发和测试工具&#xff0c;专为简化Web服务API的开发、测试、文档编制和协作过程而设计。它支持各种HTTP请求方法&#xff0c;包括GET、POST、PUT、DELETE等&#xff0c;允许用户轻松地构建和发送请求&#xff0c;以及检查响应。 本文介绍几个提升效…

Linux信号:信号的概念及意义

目录 一、什么是信号 kill-l查看信号 二、信号的产生 2.1系统调用 kill raise abort 2.2软件条件 13)SIGPIPE pipe信号 14&#xff09;SIGAKARM alarm信号 2.2硬件中断 2.3异常 8)SIGFPE 除0异常 11)SIGSEGV 野指针 2.4信号处理的常见方式 三、Core Dump和term…

docker如何拉取redis最新镜像并运行

要拉取Docker Hub上最新版本的Redis镜像&#xff0c;您可以使用以下命令&#xff1a; docker pull redis:latest 这里的latest标签会自动获取Redis镜像的最新版本。如果您希望指定一个确切的版本号&#xff0c;可以直接使用该版本号替换latest。例如&#xff0c;要拉取Redis版…

Python | Leetcode Python题解之第108题将有序数组转换为二叉搜索树

题目&#xff1a; 题解&#xff1a; class Solution:def sortedArrayToBST(self, nums: List[int]) -> TreeNode:def helper(left, right):if left > right:return None# 选择任意一个中间位置数字作为根节点mid (left right randint(0, 1)) // 2root TreeNode(nums…

计算机网络数据链路层知识点总结

3.1 数据链路层功能概述 &#xff08;1&#xff09;知识总览 &#xff08;2&#xff09;数据链路层的研究思想 &#xff08;3&#xff09;数据链路层基本概念 &#xff08;4&#xff09;数据链路层基本功能 3.1 封装成帧和透明传输 &#xff08;1&#xff09;数据链路层功能…

上海亚商投顾:三大指数均跌超1.3%,全市场下跌个股超4600只

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 市场全天震荡调整&#xff0c;三大股指均跌超1.3%。PEEK概念股逆势大涨&#xff0c;肯特股份、沃特股份涨停&a…

[STM32-HAL库]AS608-指纹识别模块-STM32CUBEMX开发-HAL库开发系列-主控STM32F103C8T6

目录 一、前言 二、详细步骤 1.光学指纹模块 2.配置STM32CUBEMX 3.程序设计 3.1 输出重定向 3.2 导入AS608库 3.3 更改端口宏定义 3.4 添加中断处理部分 3.5 初始化AS608 3.6 函数总览 3.7 录入指纹 3.8 验证指纹 3.9 删除指纹 3.10 清空指纹库 三、总结及资源 一、前言 …

AI赋能 企业智能化应用实践

前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家&#xff1a;https://www.captainbed.cn/z ChatGPT体验地址 文章目录 前言云定价优化语音助手与聊天机器人预测性维护客服运营自动化低功耗微处理器神…