当前位置: 首页 > news >正文

集合框架:Set集合的特点、HashSet集合的底层原理、哈希表、实现去重复

Set集合的特点

Set(集合)是一种无序的、不重复的数据结构,它的特点如下:

1. 集合中的元素是无序的:Set 中的元素没有顺序,无法通过索引来访问。

2. 集合中的元素是唯一的:Set 中不允许有重复的元素,每个元素在集合中只能出现一次。

3. 内部实现采用哈希表或树形结构:Set 内部通常是基于哈希表或平衡树等数据结构实现的。

4. 可以用于去重和快速查找:因为 Set 中的元素是唯一的,所以可以很方便地用来做去重操作。同时,由于内部实现采用哈希表或树形结构,所以查找某个元素的时间复杂度为 O(1) 或 O(log n)。

5. Set 中的元素必须是可哈希的:由于 Set 中的元素是基于哈希表实现的,所以集合中的元素必须是可哈希的,即元素必须有一个明确的哈希值。如果一个元素没有哈希值,那么它就不能被用作 Set 的元素。

注意:

Set要用到的常用方法,基本上就是Collection提供的!自己几乎没有额外新增一些常用方法!

练习代码

import java.util.Set;
import java.util.TreeSet;public class Test_set {public static void main(String[] args) {//1.创建一个set集合对象//HashSet:无序,不重复,无索引//Set<Integer> set = new HashSet<>(); //创建了一个HashSet的集合对象   一行经典代码//LinkedHashSet:有序,不重复,无索引//Set<Integer> set = new LinkedHashSet<>(); //创建了一个LinkedHashSet的集合对象//TreeSet:可排序(默认升序),不重复,无索引Set<Integer> set = new TreeSet<>(); //创建了一个TreeSet的集合对象set.add(666);set.add(555);set.add(555);set.add(888);set.add(888);set.add(777);set.add(777);System.out.println(set);}
}

哈希值

在学习HashSet集合的底层原理之前,我们先来了解一下什么是哈希值↓↓↓

概念

哈希值(Hash Value)是指将任意长度的数据映射为固定长度的值,通常用一个整数或固定长度的字节数组表示。哈希值也被称为散列值(Hash Code)或摘要(Digest)。

特点

在计算机领域,哈希值经常用于数据的存储、索引和加密等操作。它具有以下特点:

1. 哈希值是固定长度的:无论输入数据的长度是多少,哈希函数都会生成固定长度的哈希值。例如,常见的哈希算法 MD5 生成的哈希值为 128 位,SHA-1 的哈希值为 160 位。

2. 输入数据的微小改变会导致哈希值的巨大变化:只需改变输入数据的微小部分,哈希值就会发生巨大的变化。这种特性称为"雪崩效应",使得哈希值在校验数据的完整性时非常有用。

3. 哈希值一般是不可逆的:通常情况下,根据哈希值无法推导出原始数据的内容。哈希函数设计成使得产生相同哈希值的原始数据非常困难。

4. 相同的输入数据生成相同的哈希值:哈希函数对于相同的输入数据总是生成相同的哈希值,这方便进行数据的存储和比较。

5. 哈希值的分布应该均匀:良好的哈希函数应该能够将输入数据均匀地映射到哈希值空间,尽量避免碰撞(多个不同的输入数据生成相同的哈希值)。

java中Object类提供的public int hashCode()方法可以返回对象的哈希码值。

HashSet集合的底层原理

在 HashSet 中,元素被存储在一个 HashMap 的实例中,其中元素的值作为键(key),而键的哈希值(通过调用元素的 hashCode() 方法)则用来确定元素在哈希表中的位置。当要将一个元素加入 HashSet 时,HashSet 会首先计算该元素的哈希值,然后找到对应的存储位置。如果该位置上已经存在了元素,HashSet 会使用 equals() 方法来检查这两个元素是否相等,如果相等则认为是重复元素,不会将其加入集合。

简单来说,HashSet 的底层原理是基于哈希表实现的,使用哈希值来快速查找元素,并提供了高效的添加、删除和查找操作。

哈希表

既然HashSet集合是基于哈希表实现的,那么我们就来学习下哈希表↓↓↓

哈希表(Hash table,也叫散列表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。

给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。

实现去重复

先来看一段代码

import java.util.HashSet;
import java.util.Set;public class Test {public static void main(String[] args) {//深入了解HashSet的去重复机制Set<Student> students = new HashSet<>();Student st1 = new Student("至尊宝",18,167.5);Student st2 = new Student("蜘蛛精",22,169.8);Student st3 = new Student("蜘蛛精",22,169.8);Student st4 = new Student("牛魔王",19,183.5);students.add(st1);students.add(st2);students.add(st3);students.add(st4);System.out.println(students);}
}

运行一下

这里面有两个内容相同的不同对象st1和st2,那么HashSet集合默认是不能去重复的。在实际操作中,我们希望只留下一个对象来表示,该怎么做呢?

//内容一样的两个对象,HashSet认为他们是不重复的/*
如果希望Set集合认为两个内容一样的对象是重复的,必须重写对象的hashcode()和equals()方法*/

我们可以去Student类中重写hashcode()和equals()方法

import java.util.Objects;public class Student {private String name;private int age;private double height;public Student() {}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return age == student.age && Double.compare(height, student.height) == 0 && Objects.equals(name, student.name);}@Overridepublic int hashCode() {return Objects.hash(name, age, height);}public Student(String name, int age, double height) {this.name = name;this.age = age;this.height = height;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public double getHeight() {return height;}public void setHeight(double height) {this.height = height;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +", height=" + height +'}';}
}

这样就只会有一个蜘蛛精留下了↓

篇幅问题,这篇博客到此结束了,下一篇文章我会详细介绍JDK8前后的两种哈希表,需要的朋友可以留意一下~

相关文章:

集合框架:Set集合的特点、HashSet集合的底层原理、哈希表、实现去重复

Set集合的特点 Set&#xff08;集合&#xff09;是一种无序的、不重复的数据结构&#xff0c;它的特点如下&#xff1a; 1. 集合中的元素是无序的&#xff1a;Set 中的元素没有顺序&#xff0c;无法通过索引来访问。 2. 集合中的元素是唯一的&#xff1a;Set 中不允许有重复…...

【T690 之十二】基于方寸EVB2开发板(T690芯片)构建基于GMSSL的文件系统的方式

备注&#xff1a; 1&#xff0c;假设您已对方寸微电子的T690系列芯片的使用方式都有了一定的了解&#xff0c;然后需要构建基于GMSSL的文件系统&#xff0c;此文才对您有意义&#xff1b; 2&#xff0c;若您对方寸微电子的T690芯片不了解&#xff0c;但想进一步了解它&#xff…...

使用Selenium发邮件附件

发邮件可以使用SMTP协议实现程序去发送&#xff0c;但附件的不能太大&#xff0c;一般不超过20M。 以下使用Selenium模拟发送邮件&#xff0c;跳过这个限制&#xff0c;网上找了很多资料&#xff0c;都没有完整实现的&#xff0c;那么自己实现一个&#xff0c;以下代码用Python…...

公共数据这座金矿,授权运营为何是赋能的关键路径?

数据要素市场化正开启下一个关键阶段。 自2014年大数据写入政府工作报告&#xff0c;到全国各地大数据交易所涌现&#xff0c;再到《数据二十条》颁布&#xff0c;中国数据要素产业探索之路已走过近十载。如今&#xff0c;国家大数据局正式成立&#xff0c;更是标志着数据要素…...

昇腾CANN 7.0 黑科技:大模型推理部署技术解密

CANN作为最接近昇腾AI系列硬件产品的一层&#xff0c;通过软硬件联合设计&#xff0c;打造出适合昇腾AI处理器的软件架构&#xff0c;充分使能和释放昇腾硬件的澎湃算力。针对大模型推理场景&#xff0c;CANN最新发布的CANN 7.0版本有机整合各内部组件&#xff0c;支持大模型的…...

OAuth 2.0

OAuth 2.0 是一种授权机制&#xff0c;允许应用程序访问第三方服务的用户数据&#xff0c;而不需要用户提供用户名和密码。其原理包括以下几个步骤&#xff1a; 应用程序向第三方服务请求授权&#xff0c;并提供自己的身份信息。 第三方服务向用户展示授权请求的具体内容和应用…...

7个设计师必备的Figma汉化插件,高效设计超简单!

Figma是一个著名的在线设计工具&#xff0c;拥有来自全球各地的超多设计师都在用&#xff0c;粉丝多多。其强大和灵活的设计功能使许多设计师都喜欢使用它。然而&#xff0c;为了进一步提高设计效率和扩展功能&#xff0c;许多开发人员开发了各种有用的Figma设计的汉化插件。在…...

缓存-基础理论和Guava Cache介绍

缓存-基础理论和Guava Cache介绍 缓存基础理论 缓存的容量和扩容 缓存初始容量、最大容量&#xff0c;扩容阈值以及相应的扩容实现。 缓存分类 本地缓存&#xff1a;运行于本进程中的缓存&#xff0c; 如Java的 concurrentHashMap, Ehcache&#xff0c;Guava Cache。 分布式缓…...

机器人伺服驱动控制环

伺服驱动器​的控制环&#xff0c;包括&#xff1a;位置环、速度环、电流环这三种类型。 对于伺服的控制回路&#xff0c;内侧控制环的响应带宽一般会是外侧控制环的5到10倍。也就是说&#xff0c;电流环带宽大致是速度环的5到10倍&#xff0c;速度环带宽则约为位置环的5到10倍…...

单链表(3)

现在有一个指针p&#xff0c;指向数据2所在的结点的地址——那么如何访问这个数据2 前面说过指针访问数据成员使用的是 指向符->。则访问这个数据2就是——p->data.因为p一开始就指向数据2的结点地址了 那么如何访问数据3,4往后等等 访问3就是——p->next->data…...

Android14前台服务适配指南

Android14前台服务适配指南 Android 10引入了android:foregroundServiceType属性&#xff0c;用于帮助开发者更有目的地定义前台服务。这个属性在Android 14中被强制要求&#xff0c;必须指定适当的前台服务类型。以下是可选择的前台服务类型&#xff1a; camera: 相机应用。…...

Spring Boot中使用Spring Data JPA访问MySQL

Spring Data JPA是Spring框架提供的用于简化JPA&#xff08;Java Persistence API&#xff09;开发的数据访问层框架。它通过提供一组便捷的API和工具&#xff0c;简化了对JPA数据访问的操作&#xff0c;同时也提供了一些额外的功能&#xff0c;比如动态查询、分页、排序等。 …...

Go 语言函数闭包(匿名函数)

Go 语言函数闭包&#xff08;匿名函数&#xff09; 在Go语言中&#xff0c;闭包是一种特殊的匿名函数&#xff0c;它可以捕获并访问其周围的变量。闭包允许将函数与其引用的环境捆绑在一起&#xff0c;使得函数可以在其创建的范围之外继续使用这些变量。以下是关于Go语言闭包的…...

2023年11月编程语言流行度排名

点击查看最新编程语言流行度排名&#xff08;每月更新&#xff09; 2023年11月编程语言流行度排名 编程语言流行度排名是通过分析在谷歌上搜索语言教程的频率而创建的 一门语言教程被搜索的次数越多&#xff0c;大家就会认为该语言越受欢迎。这是一个领先指标。原始数据来自…...

apache-maven-3.6.3 安装配置教程

链接&#xff1a;https://pan.baidu.com/s/1RkMXipnvac9EKcZyUStfGQ?pwdl32m 提取码&#xff1a;l32m 1. 将 maven 压缩包解压至指定文件夹 2. 配置环境变量 &#xff08;1&#xff09;打开此电脑-> 鼠标右键选择属性->点击高级系统设置 &#xff08;2&#xff09;点…...

你一般什么时候使用GPT

一般在寻求帮助的时候才使用gpt 一个优秀的gpt项目gpt-on-web...

kubernetes (k8s)的使用

一、kubernetes 简介 谷歌2014年开源的管理工具项目&#xff0c;简化微服务的开发和部署。 提供功能&#xff1a;自愈和自动伸缩、调度和发布、调用链监控、配置管理、Metrics监控、日志监控、弹性和容错、API管理、服务安全等。官网&#xff1a;https://kubernetes.io/zh-cn…...

RK3568平台开发系列讲解(音视频篇)RTMP 推流

🚀返回专栏总目录 文章目录 一、RTMP 的工作原理二、RTMP 流媒体服务框架2.1、Nginx 流媒体服务器2.2、FFmpeg 推流沉淀、分享、成长,让自己和他人都能有所收获!😄 📢目前常见的视频监控和视频直播都是使用了 RTMP、RTSP、HLS、MPEG-DASH、 WebRTC流媒体传输协议等。 R…...

掌握这几个技巧,才敢称为Jenkins大神!

01、Performance插件兼容性问题 自由风格项目中&#xff0c;有使用 Performance 插件收集构建产物&#xff0c;但是截至到目前最新版本&#xff08;Jenkins v2.298&#xff0c;Performance&#xff1a;v3.19&#xff09;&#xff0c;此插件和Jenkins都存在有兼容性问题&#xf…...

帷幄内容管理系统:从立人设、做内容到定向投流,品牌 KOS 体系打造「百万导购」

随着公域流量越来越贵&#xff0c;获客成本越来越高&#xff0c;品牌们已经越来越不满足于高曝光&#xff0c;而是更多地关注起销售转化率。继 KOL、KOC&#xff08;关键意见消费者&#xff09; 之后&#xff0c;KOS&#xff08;关键意见销售&#xff09;营销模式走入品牌的视野…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

TDengine 快速体验(Docker 镜像方式)

简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能&#xff0c;本节首先介绍如何通过 Docker 快速体验 TDengine&#xff0c;然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker&#xff0c;请使用 安装包的方式快…...

golang循环变量捕获问题​​

在 Go 语言中&#xff0c;当在循环中启动协程&#xff08;goroutine&#xff09;时&#xff0c;如果在协程闭包中直接引用循环变量&#xff0c;可能会遇到一个常见的陷阱 - ​​循环变量捕获问题​​。让我详细解释一下&#xff1a; 问题背景 看这个代码片段&#xff1a; fo…...

SciencePlots——绘制论文中的图片

文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了&#xff1a;一行…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

uniapp中使用aixos 报错

问题&#xff1a; 在uniapp中使用aixos&#xff0c;运行后报如下错误&#xff1a; AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...

【数据分析】R版IntelliGenes用于生物标志物发现的可解释机器学习

禁止商业或二改转载&#xff0c;仅供自学使用&#xff0c;侵权必究&#xff0c;如需截取部分内容请后台联系作者! 文章目录 介绍流程步骤1. 输入数据2. 特征选择3. 模型训练4. I-Genes 评分计算5. 输出结果 IntelliGenesR 安装包1. 特征选择2. 模型训练和评估3. I-Genes 评分计…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈&#xff0c;并不断增加特征维度持续测试」的做法&#xff0c;体现了一种逐步建模与迭代验证的实验思路&#xff0c;在金融欺诈检测中非常有价值&#xff0c;本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...

LangFlow技术架构分析

&#x1f527; LangFlow 的可视化技术栈 前端节点编辑器 底层框架&#xff1a;基于 &#xff08;一个现代化的 React 节点绘图库&#xff09; 功能&#xff1a; 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...