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

【Java】—— 集合框架:Collection子接口:Set不同实现类的对比及使用(HashSet、LinkedHashSet、TreeSet)

目录

5. Collection子接口2:Set

5.1 Set接口概述

5.2 Set主要实现类:HashSet

5.2.1 HashSet概述

5.2.2 HashSet中添加元素的过程:

5.2.3 重写 hashCode() 方法的基本原则

5.2.4 重写equals()方法的基本原则

5.2.5 练习

5.3 Set实现类之二:LinkedHashSet

5.4 Set实现类之三:TreeSet

5.4.1 TreeSet概述


5. Collection子接口2:Set

5.1 Set接口概述

  • Set接口是Collection的子接口,Set接口相较于Collection接口没有提供额外的方法

  • Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。

  • Set集合支持的遍历方式和Collection集合一样:foreach和Iterator。

  • Set的常用实现类有:HashSet、TreeSet、LinkedHashSet。

5.2 Set主要实现类:HashSet

5.2.1 HashSet概述
  • HashSet 是 Set 接口的主要实现类,大多数时候使用 Set 集合时都使用这个实现类。

  • HashSet 按 Hash 算法来存储集合中的元素,因此具有很好的存储、查找、删除性能。

  • HashSet 具有以下特点

    • 不能保证元素的排列顺序

    • HashSet 不是线程安全的

    • 集合元素可以是 null

  • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法得到的哈希值相等,并且两个对象的 equals()方法返回值为true

  • 对于存放在Set容器中的对象,对应的类一定要重写hashCode()和equals(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。

  • HashSet集合中元素的无序性,不等同于随机性。这里的无序性与元素的添加位置有关。具体来说:我们在添加每一个元素到数组中时,具体的存储位置是由元素的hashCode()调用后返回的hash值决定的。导致在数组中每个元素不是依次紧密存放的,表现出一定的无序性。

5.2.2 HashSet中添加元素的过程:
  • 第1步:当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法得到该对象的 hashCode值,然后根据 hashCode值,通过某个散列函数决定该对象在 HashSet 底层数组中的存储位置。

  • 第2步:如果要在数组中存储的位置上没有元素,则直接添加成功。

  • 第3步:如果要在数组中存储的位置上有元素,则继续比较:

    • 如果两个元素的hashCode值不相等,则添加成功;

    • 如果两个元素的hashCode()值相等,则会继续调用equals()方法:

      • 如果equals()方法结果为false,则添加成功。

      • 如果equals()方法结果为true,则添加失败。

    第2步添加成功,元素会保存在底层数组中。

    第3步两种添加成功的操作,由于该底层数组的位置已经有元素了,则会通过链表的方式继续链接,存储。

5.2.3 重写 hashCode() 方法的基本原则
  • 在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。

  • 当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。

  • 对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。

注意:如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

5.2.4 重写equals()方法的基本原则
  • 重写equals方法的时候一般都需要同时复写hashCode方法。通常参与计算hashCode的对象的属性也应该参与到equals()中进行计算。

  • 推荐:开发中直接调用Eclipse/IDEA里的快捷键自动重写equals()和hashCode()方法即可

    • 为什么用Eclipse/IDEA复写hashCode方法,有31这个数字?

首先,选择系数的时候要选择尽量大的系数。因为如果计算出来的hash地址越大,所谓的“冲突”就越少,查找起来效率也会提高。(减少冲突)

其次,31只占用5bits,相乘造成数据溢出的概率较小。

再次,31可以 由i*31== (i<<5)-1来表示,现在很多虚拟机里面都有做相关优化。(提高算法效率)

最后,31是一个素数,素数作用就是如果我用一个数字来乘以这个素数,那么最终出来的结果只能被素数本身和被乘数还有1来整除!(减少冲突)

5.2.5 练习

练习1:在List内去除重复数字值,要求尽量简单

public static List duplicateList(List list) {HashSet set = new HashSet();set.addAll(list);return new ArrayList(set);
}
public static void main(String[] args) {List list = new ArrayList();list.add(new Integer(1));list.add(new Integer(2));list.add(new Integer(2));list.add(new Integer(4));list.add(new Integer(4));List list2 = duplicateList(list);for (Object integer : list2) {System.out.println(integer);}
}

练习2:获取随机数

        编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。

public class RandomValueTest {public static void main(String[] args) {HashSet hs = new HashSet(); // 创建集合对象Random r = new Random();while (hs.size() < 10) {int num = r.nextInt(20) + 1; // 生成1到20的随机数hs.add(num);}for (Integer integer : hs) { // 遍历集合System.out.println(integer); // 打印每一个元素}}
}

练习3:去重

        使用Scanner从键盘读取一行输入,去掉其中重复字符,打印出不同的那些字符。比如:aaaabbbcccddd

public class DistinctTest {public static void main(String[] args) {Scanner sc = new Scanner(System.in); // 创建键盘录入对象System.out.println("请输入一行字符串:");String line = sc.nextLine(); // 将键盘录入的字符串存储在line中char[] arr = line.toCharArray(); // 将字符串转换成字符数组HashSet hs = new HashSet(); // 创建HashSet集合对象for (Object c : arr) { // 遍历字符数组hs.add(c); // 将字符数组中的字符添加到集合中}for (Object ch : hs) { // 遍历集合System.out.print(ch);}}
}

5.3 Set实现类之二:LinkedHashSet

  • LinkedHashSet 是 HashSet 的子类,不允许集合元素重复。

  • LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以添加顺序保存的。

  • LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

5.4 Set实现类之三:TreeSet

5.4.1 TreeSet概述
  • TreeSet 是 SortedSet 接口的实现类,TreeSet 可以按照添加的元素的指定的属性的大小顺序进行遍历。

  • TreeSet底层使用红黑树结构存储数据

  • 新增的方法如下: (了解)

    • Comparator comparator()

    • Object first()

    • Object last()

    • Object lower(Object e)

    • Object higher(Object e)

    • SortedSet subSet(fromElement, toElement)

    • SortedSet headSet(toElement)

    • SortedSet tailSet(fromElement)

  • TreeSet特点:不允许重复、实现排序(自然排序或定制排序)

  • TreeSet 两种排序方法:自然排序定制排序。默认情况下,TreeSet 采用自然排序。

    • 自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。

      • 如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。

      • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。

    • 定制排序:如果元素所属的类没有实现Comparable接口,或不希望按照升序(默认情况)的方式排列元素或希望按照其它属性大小进行排序,则考虑使用定制排序。定制排序,通过Comparator接口来实现。需要重写compare(T o1,T o2)方法。

      • 利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。

      • 要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。

  • 因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象

  • 对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 compareTo(Object obj) 或compare(Object o1,Object o2)方法比较返回值。返回值为0,则认为两个对象相等。

相关文章:

【Java】—— 集合框架:Collection子接口:Set不同实现类的对比及使用(HashSet、LinkedHashSet、TreeSet)

目录 5. Collection子接口2&#xff1a;Set 5.1 Set接口概述 5.2 Set主要实现类&#xff1a;HashSet 5.2.1 HashSet概述 5.2.2 HashSet中添加元素的过程&#xff1a; 5.2.3 重写 hashCode() 方法的基本原则 5.2.4 重写equals()方法的基本原则 5.2.5 练习 5.3 Set实现类…...

android Activity生命周期

android 中一个 activity 在其生命周期中会经历多种状态。 您可以使用一系列回调来处理状态之间的转换。下面我们来介绍这些回调。 onCreate&#xff08;创建阶段&#xff09; 初始化组件&#xff1a;在这个阶段&#xff0c;Activity的主要工作是进行初始化操作。这包括为Ac…...

C#的面向对象

1&#xff09;对象 算法数据结构 2&#xff09;对象的行为已方法的形式定义的&#xff0c;属性以成员变量的形式定义的 面向对象程序设计的特点 1&#xff09;封装性 2&#xff09;继承性 3&#xff09;多态性 知识点&#xff1a; 封装性面向对象的核心思想&#xff0c;将…...

【区别】三种命令取消已暂存的文件,处理暂存区和文件的跟踪状态

取消已暂存的文件 git restore --staged <文件>、git reset HEAD <文件> 和 git rm --cached <文件> 都可以用于取消已暂存的文件&#xff0c;但它们的作用和使用场景略有不同。下面是它们的区别&#xff1a; 1. git restore --staged <文件> 该命令…...

如何在Spring Boot中有条件地运行CommandLineRunner Bean

PS 使用 Spring Boot 3.1.2 进行测试 1.使用ConditionalOnProperty ConditionalOnProperty仅当特定属性存在或具有特定值时&#xff0c;注释才会创建 Bean 。 在此示例中&#xff0c;仅当或文件中的CommandLineRunner属性db.init.enabled设置为 true时&#xff0c;才会执行。…...

边缘自适应粒子滤波(Edge-Adaptive Particle Filter)的MATLAB函数示例,以及相应的讲解

目录 讲解 初始化 预测步骤 观测模拟 权重更新 重采样 状态估计 总结 下面是一个简单的边缘自适应粒子滤波&#xff08;&#xff09;的函数示例&#xff0c;以及相应的讲解。 程序源代码&#xff1a; function X_est edgeAdaptiveParticleFilter(numParticles, numS…...

一块1T硬盘怎么有sdb1和sdb2

在一块 1TB 硬盘上看到两个分区 sdb1 和 sdb2 是非常常见的现象。硬盘可以被划分为多个分区&#xff0c;每个分区都可以用作不同的目的&#xff0c;如存储不同类型的数据、安装不同的操作系统或为系统不同的功能提供支持。 1. 分区的概念 硬盘可以被划分为多个分区&#xff0…...

Python知识点:如何使用Flink与Python进行实时数据处理

开篇&#xff0c;先说一个好消息&#xff0c;截止到2025年1月1日前&#xff0c;翻到文末找到我&#xff0c;赠送定制版的开题报告和任务书&#xff0c;先到先得&#xff01;过期不候&#xff01; 如何使用Flink与Python进行实时数据处理 Apache Flink是一个流处理框架&#xf…...

Swagger配置且添加小锁(asp.net)(笔记)

此博客是基于 asp.net core web api(.net core3.1)框架进行操作的。 一、安装Swagger包 在 NuGet程序包管理中安装下面的两个包&#xff1a; swagger包&#xff1a;Swashbuckle.AspNetCore swagger包过滤器&#xff1a;Swashbuckle.AspNetCore.Filters 二、swagger注册 在…...

lambda表达式底层实现:反编译LambdaMetafactory + 转储dump + 运行过程 + 反汇编 + 动态指令invokedynamic

一、结论先行 lambda 底层实现机制 1.lambda 表达式的本质&#xff1a;函数式接口的匿名子类的匿名对象 2.lambda表达式是语法糖 语法糖&#xff1a;编码时是lambda简洁的表达式&#xff0c;在字节码期&#xff0c;语法糖会被转换为实际复杂的实现方式&#xff0c;含义不变&am…...

Unity初识+面板介绍

Unity版本使用 小版本号高&#xff0c;出现bug可能性更小&#xff1b;一台电脑可以安装多个版本的Unity&#xff0c;但是需要安装在不同路径&#xff1b;安装Unity时不能有中文路径&#xff1b;Unity项目路径也不要有中文。 Scene面板 相当于拍电影的片场&#xff0c;Unity程…...

【CSS in Depth 2 精译_041】6.4 CSS 中的堆叠上下文与 z-index(上)

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 第一章 层叠、优先级与继承&#xff08;已完结&#xff09;第二章 相对单位&#xff08;已完结&#xff09;第三章 文档流与盒模型&#xff08;已完结&#xff09;第四章 Flexbox 布局&#xff08;已…...

uniapp微信小程序巧用跳转封装鉴权路由

1.这是封装的跳转方法&#xff1a; import store from "../stores/store";function Router(type, url, params) {const NoLoginPage [。。。。。];var queryString Object.keys(params).map((key) > ${key}${params[key]}).join("&");if (!NoLog…...

国外电商系统开发-运维系统开发

因项目运营环境在国外&#xff0c;所以必须将服务器选择国外&#xff0c;加上第一次运营国外项目。在两大趋势下&#xff0c;企业的运营方向必须通过大数据来分析及修正运营方向&#xff0c;加上后期服务器数量日益增多&#xff0c;如何有效的管理众多的服务器及验证运营方向&a…...

基于投影滤波算法的rick合成地震波滤波matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 RICK合成地震波模型 4.2 投影滤波算法原理 5.完整工程文件 1.课题概述 基于投影滤波算法的rick合成地震波滤波matlab仿真。分别通过标准的滤波投影滤波以及卷积滤波投影滤波对合成地震剖面进行滤波…...

【艾思科蓝】机器学习框架终极指南:PyTorch vs TensorFlow vs Keras vs Scikit-learn

第十届建筑、土木与水利工程国际学术会议(ICACHE 2024)_艾思科蓝_学术一站式服务平台 更多学术会议请看&#xff1a;学术会议-学术交流征稿-学术会议在线-艾思科蓝 目录 引言 1. PyTorch PyTorch的特点 PyTorch的用例 PyTorch的安装 PyTorch代码示例 2. TensorFlow …...

招联金融秋招内推2025

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递&#xff09; 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...

遮罩解决图片悬浮操作看不到的情况

未悬浮效果 悬浮效果 如果仅仅是添加绝对定位&#xff0c;那么遇到白色图片&#xff0c;就会看不到白色字体。通过遮罩&#xff08;绝对定位透明度&#xff09;就可以解决这个问题。 <script setup> </script><template><div class"box"><…...

IoT网关的主要功能有哪些?天拓四方

在数字化浪潮席卷全球的今天&#xff0c;物联网&#xff08;IoT&#xff09;技术凭借其独特的优势&#xff0c;逐渐在各个领域展现出强大的生命力。而IoT网关&#xff0c;作为连接物理世界与数字世界的桥梁&#xff0c;其在物联网体系中的作用愈发凸显。 一、数据聚合与预处理…...

继承实现单例模式的探索(一)

前言 之前看到朋友采用继承的方式来实现单例模式&#xff0c;觉得很厉害&#xff0c;随后自己去探索了一番&#xff0c;以前实现单例模式都是把代码内联到具体的类中&#xff0c;这使得工程中每次需要使用单例模式时&#xff0c;都采用拷贝的方式&#xff0c;增加了很多冗余代码…...

【代码实现】opencv 高斯模糊和pytorch 高斯模糊

wiki百科 Gaussian Blur&#xff0c;也叫高斯平滑&#xff0c;是在Adobe Photoshop、GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果&#xff0c;通常用它来减少图像噪声以及降低细节层次。 opencv实现 opencv实现高斯滤波有两种方式&#xff0c; 1、是使用自带的cv2…...

python基础语法2

文章目录 1.顺序语句2.条件语句2.1 语法格式 3.缩进与代码块4.空语句 pass5.循环语句5.1 while循环5.2 for循环 5.3 continue与break 1.顺序语句 默认情况下&#xff0c;python的代码都是按照从上到下的顺序依次执行的。 print(hello ) print(world)结果一定是hello world。写…...

linux第一课:下载与安装

这是我的个人复习笔记&#xff0c;草稿箱字太多会卡就发这了&#xff0c;欢迎大家阅读。 Kali Linux&#xff0c;黑客必备神器。跟着我&#xff0c;带你从入门到入狱&#xff01; 第一课&#xff0c;下载与安装。 第一步&#xff1a; 在官网下载Centos镜像&#xff1a;http…...

虚拟机添加共享文件夹后仍无法显示文件

参考: https://blog.csdn.net/Pretender_1205/article/details/134859089 进入/mnt/hgfs目录下执行 sudo mount -t fuse.vmhgfs-fuse .host:/ /mnt/hgfs -o allow_other/mnt/hgfs 是挂载点&#xff0c;也可以修改为其他挂载点-o allow_other表示允许其他用户(普通用户)访问共…...

OSPF协议

基础知识 OSPF:开放式最短路径优先协议 (无类别链路状态IGP动态协议) OSPF的特点&#xff1a; 1.OSPF将自治系统划分为逻辑上的区域&#xff0c;使用LSA来发布路由信息&#xff0c;并通过OSPF报文在区域内路由器之间交互建立链路状态数据库和路由表 2.支持等开销的负载均衡…...

行为设计模式 -观察者模式- JAVA

观察者模式 一.简介二. 案例2.1 抽象主题&#xff08;Subject&#xff09;2.2 具体主题&#xff08;Concrete Subject&#xff09;2.3 抽象观察者&#xff08;Observer&#xff09;2.4 具体观察者&#xff08;Concrete Observer&#xff09;2.5 测试 三. 结论3.1 优缺点3.2 使用…...

在阿里工作是一种什么体验?

很多人都对在阿里工作感到好奇&#xff0c;今天就来给大家分享一下在阿里工作是一种什么体验~ 首先&#xff0c;先来介绍一下阿里的职位等级划分标准。 简单来讲&#xff0c;阿里的职位等级可以认为是 P 序列和 M 序列&#xff0c;但目前 M 序列已经不太对中下层员工开放了&…...

828华为云征文|华为云Flexus云服务器X实例——uniapp功能开发、搭建股票系统选择用什么服务器比较好?

在二次开发、安装搭建股票系统时&#xff0c;选择华为云Flexus X服务器是一个值得考虑的优质选项。以下是一些具体的建议&#xff1a; 测试环境&#xff1a;Linux系统CentOS7.6、宝塔、PHP7.3、MySQL5.7&#xff0c;根目录public&#xff0c;伪静态thinkphp&#xff0c;开启ssl…...

电子电路元件器介绍与选型——晶振

一、晶振 在我们使用嘉立创的时候&#xff0c;经常会看到晶振接到两个电容&#xff0c;这两个电容毫无疑问是滤波的&#xff0c;整个晶振其实就是一个振荡器&#xff0c;但这个振荡器会将其他频率给过滤掉&#xff0c;只保留一个频率也就是晶振的标称频率。当然上面讲的很明显是…...

【IEEE PDF eXpress】格式不对

目录 一、问题二、解决方法 一、问题 word的文档&#xff0c;用IEEE PDF eXpress网站生成pdf后&#xff0c;提交论文出现错误&#xff1a; Document validation failed due to the following errors: Content exceeds IEEE template margins for its format (Page 1:Bottom).…...