Java 中 HashSet 集合元素的去重

目录

一、认识 HashSet:独特的 “去重小能手”

二、HashSet 的去重原理

三、代码示例:直观感受 HashSet 的去重魅力

1. 添加基本数据类型包装类元素

2. 添加自定义类元素

四、HashSet 去重的注意事项


 

在 Java 编程的广阔天地里,集合框架是开发者们不可或缺的得力工具。其中,HashSet以其独特的去重特性,成为处理不重复元素场景的首选。今天,咱们就深入探究一下HashSet集合元素的去重操作,通过具体的代码示例,揭开它那神秘的面纱。

一、认识 HashSet:独特的 “去重小能手”

HashSet是 Java 集合框架中Set接口的一个实现类,它的主要特点就是不允许存储重复的元素。这就好比一个神奇的收纳盒,不管你往里面放多少东西,相同的物品只会被保留一份。从底层实现来看,HashSet是基于HashMap来实现的,它利用哈希表的特性来快速定位和存储元素,从而高效地实现去重功能。

二、HashSet 的去重原理

在深入代码之前,先了解一下HashSet的去重原理。当我们向HashSet中添加一个元素时,HashSet会先调用该元素的hashCode()方法,计算出该元素的哈希码。哈希码就像是元素的一个 “数字指纹”,通过这个 “指纹” 可以快速定位元素在哈希表中的存储位置。如果两个元素的哈希码相同,HashSet会进一步调用equals()方法来判断这两个元素是否相等。只有当两个元素的哈希码相同且equals()方法返回true时,HashSet才会认为这两个元素是重复的,不会将第二个元素添加进去。

三、代码示例:直观感受 HashSet 的去重魅力

1. 添加基本数据类型包装类元素

import java.util.HashSet;
import java.util.Set;public class HashSetPrimitiveWrapperExample {public static void main(String[] args) {Set<Integer> numberSet = new HashSet<>();numberSet.add(10);numberSet.add(20);numberSet.add(10); // 尝试添加重复元素System.out.println("HashSet中的元素: " + numberSet);}
}

在上述代码中,我们创建了一个HashSet来存储Integer类型的元素。首先添加了1020,然后再次尝试添加10。运行程序后,你会发现输出结果中10只出现了一次,这就是HashSet的去重效果。

2. 添加自定义类元素

当我们尝试向HashSet中添加自定义类的对象时,情况会稍微复杂一些。因为默认情况下,自定义类继承自Object类,其hashCode()equals()方法的实现并不能满足我们的去重需求。所以,我们需要在自定义类中重写这两个方法。

import java.util.HashSet;
import java.util.Set;class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass()!= o.getClass()) return false;Person person = (Person) o;return age == person.age && name.equals(person.name);}@Overridepublic int hashCode() {int result = 17;result = 31 * result + name.hashCode();result = 31 * result + age;return result;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +'}';}
}public class HashSetCustomClassExample {public static void main(String[] args) {Set<Person> personSet = new HashSet<>();Person person1 = new Person("Alice", 25);Person person2 = new Person("Bob", 30);Person person3 = new Person("Alice", 25); // 尝试添加重复元素personSet.add(person1);personSet.add(person2);personSet.add(person3);System.out.println("HashSet中的Person对象: " + personSet);}
}

在这个例子中,我们定义了一个Person类,并在其中重写了equals()hashCode()方法。通过合理的实现,HashSet能够准确判断两个Person对象是否重复。运行程序后,你会发现person3并没有被添加到HashSet中,因为它与person1在逻辑上是重复的。

四、HashSet 去重的注意事项

  1. 重写 equals () 和 hashCode () 方法的一致性:在自定义类中重写equals()hashCode()方法时,一定要确保它们的逻辑是一致的。如果两个对象通过equals()方法比较相等,那么它们的hashCode()方法返回值也必须相同;反之,如果两个对象的hashCode()方法返回值相同,它们不一定相等,但通过equals()方法比较应该有合理的逻辑判断。
  2. 哈希碰撞的影响:虽然哈希表的设计使得哈希碰撞(即不同元素具有相同的哈希码)的概率较低,但仍然可能发生。当哈希碰撞发生时,HashSet会通过equals()方法进一步判断元素是否相等。过多的哈希碰撞可能会影响HashSet的性能,因此在设计hashCode()方法时,要尽量使哈希码分布均匀,减少碰撞的发生。

通过今天的探索,我们深入了解了 Java 中HashSet集合元素的去重操作。从基本数据类型包装类到自定义类,HashSet都能凭借其独特的去重原理,高效地处理重复元素。掌握HashSet的去重特性,不仅能让我们在处理不重复数据时更加得心应手,还能帮助我们优化程序性能。在实际编程中,根据具体需求合理使用HashSet,并注意去重过程中的一些细节,将为我们的代码增添更多的稳定性和高效性。希望大家在今后的 Java 编程之旅中,能够熟练运用HashSet的去重功能,创造出更加优秀的程序。如果在学习过程中遇到任何问题,欢迎随时交流,让我们一起在 Java 编程的世界里不断进步。

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

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

相关文章

2024年美赛C题评委文章及O奖论文解读 | AI工具如何影响数学建模?从评委和O奖论文出发-O奖论文做对了什么?

模型假设仅仅是简单陈述吗&#xff1f;允许AI的使用是否降低了比赛难度&#xff1f;还在依赖机器学习的模型吗&#xff1f;处理题目的方法有哪些&#xff1f;O奖论文的优点在哪里&#xff1f; 本文调研了当年赛题的评委文章和O奖论文&#xff0c;这些问题都会在文章中一一解答…

C语言练习(17)

两个乒乓球队进行比赛&#xff0c;各出3人。甲队为A、B、C 3人&#xff0c;乙队为X、Y、Z 3人&#xff0c;并抽签决定比赛名单。有人向队员打听比赛的名单&#xff0c;A说他不和X比&#xff0c;C说他不和X、Z比&#xff0c;请编程序找出3对选手的对阵名单。 #include <stdi…

【回忆迷宫——处理方法+DFS】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 250; int g[N][N]; bool vis[N][N]; int dx[4] {0, 0, -1, 1}; int dy[4] {-1, 1, 0, 0}; int nx 999, ny 999, mx, my; int x 101, y 101; //0墙 (1空地 2远方) bool jud(int x, int y) {if…

Flowable 审核功能封装

文章目录 引言I 查询当前用户需要审核的数据列表整体逻辑根据组获取任务数据根据审核人获取任务数据II 进行审核整体逻辑III 审核历史查询IV 流程图查看流程进度思路根据任务 ID 获取任务进度流程图引言 流程引擎功能封装 : 审核列表数据查询进行审核的整体逻辑:获取任务 Id,…

Java-数据结构-二叉树习题(2)

第一题、平衡二叉树 ① 暴力求解法 &#x1f4da; 思路提示&#xff1a; 该题要求我们判断给定的二叉树是否为"平衡二叉树"。 平衡二叉树指&#xff1a;该树所有节点的左右子树的高度相差不超过 1。 也就是说需要我们会求二叉树的高&#xff0c;并且要对节点内所…

github汉化

本文主要讲述了github如何汉化的方法。 目录 问题描述汉化步骤1.打开github&#xff0c;搜索github-chinese2.打开项目&#xff0c;打开README.md3.下载安装脚本管理器3.1 在README.md中往下滑动&#xff0c;找到浏览器与脚本管理器3.2 选择浏览器对应的脚本管理器3.2.1 点击去…

学习ASP.NET Core的身份认证(基于JwtBearer的身份认证8)

为进一步测试通过请求头传递token进行身份验证&#xff0c;在main.htm中增加layui的数据表格组件&#xff0c;并调用后台服务分页显示数据&#xff0c;后台分页查询数据接口如下所示&#xff08;测试时&#xff0c;直接将数据写死到代码中&#xff0c;没有查询数据库&#xff0…

Linux系统 C/C++编程基础——使用make工具和Makefile实现自动编译

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周二了&#xff0c;距离除夕只有&#xff16;天了&#xff0c;新的一年就快到了&#x1f606; 本文是有关Linux C/C编程的make和Makefile实现自动编译相关知识点&#xff0c;后续会不断添加相关内容 ~~ 回顾:【Emacs编辑器、G…

68,[8] BUUCTF WEB [RoarCTF 2019]Simple Upload(未写完)

<?php // 声明命名空间&#xff0c;遵循 PSR-4 自动加载规范&#xff0c;命名空间为 Home\Controller namespace Home\Controller;// 导入 Think\Controller 类&#xff0c;以便扩展该类 use Think\Controller;// 定义 IndexController 类&#xff0c;继承自 Think\Control…

可以自己部署的微博 Mastodon

Mastodon&#xff08;又称乳齿象、长毛象或万象&#xff09;是一个自由开源的去中心化的分布式微博客社交网络。它的用户界面和操作方式跟推特&#xff08;Twitter&#xff09;类似&#xff0c;但整个网路并非由单一机构运作&#xff0c;而是以多个由不同营运者独立运作的伺服器…

机器学习-核函数(Kernel Function)

核函数&#xff08;Kernel Function&#xff09;是一种数学函数&#xff0c;主要用于将数据映射到一个更高维的特征空间&#xff0c;以便于在这个新特征空间中更容易找到数据的结构或模式。核函数的主要作用是在不需要显式计算高维特征空间的情况下&#xff0c;通过内积操作来实…

AQS公平锁与非公平锁之源码解析

AQS加锁逻辑 ReentrantLock.lock public void lock() {sync.acquire(1);}AbstractQueuedSynchronizer#acquire public final void acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))selfInterrupt();}addWaiter就是将节点加入…

软件授权产品介绍

CodeMeter技术可提供高达40亿个授权模块&#xff0c;其中6000个可存放于硬件加密狗CmDongle中&#xff0c;其他可存放于软授权CmActLicense中按需激活&#xff0c;CodeMeter云授权CmCloud也可以无任何限制的为“云中软件”提供灵活的授权控制。 CodeMeter安全时钟模块采用了独…

Excel 技巧17 - 如何计算倒计时,并添加该倒计时的数据条(★)

本文讲如何计算倒计时&#xff0c;并添加该倒计时的数据条。 1&#xff0c;如何计算倒计时 这里也要用公式 D3 - TODAY() 显示为下面这个样子的 然后右键该单元格&#xff0c;选 设置单元格格式 然后点 常规 这样就能显示出还书倒计时的日数了。 下拉适用到其他单元格。 2&a…

Vue3初学之Element Plus Dialog对话框,Message组件,MessageBox组件

Dialog的使用&#xff1a; 控制弹窗的显示和隐藏 <template><div><el-button click"dialogVisible true">打开弹窗</el-button><el-dialogv-model"dialogVisible"title"提示"width"30%":before-close&qu…

C++ 类与对象(上)

在C中&#xff0c;在原来C语言基础上引入了类的概念。与C语言最大的不同就是&#xff1a;C可以在类中定义函数。由类声明的变量&#xff0c;称为对象。 1.类的定义 1.1类定义的格式 class为定义类的关键字&#xff0c;Stack为类的名字&#xff0c;{}中为类的主体&#xff0c;…

什么样的问题适合用递归

递归是一种通过函数调用自身来解决问题的方法。递归适用于那些可以被分解为相似子问题的问题&#xff0c;即原问题可以通过解决一个或多个更小规模的同类问题来解决。递归通常需要满足以下两个条件&#xff1a; 递归基&#xff08;Base Case&#xff09;&#xff1a;问题的最简…

Qt基础项目篇——Qt版Word字处理软件

一、核心功能 本软件为多文档型程序&#xff0c;界面是标准的 Windows 主从窗口 拥有&#xff1a;主菜单、工具栏、文档显示区 和 状态栏。 所要实现的东西&#xff0c;均在下图了。 开发该软件&#xff0c;主要分为下面三个阶段 1&#xff09;界面设计开发 多窗口 MDI 程序…

【物联网】keil仿真环境设置 keilV5可以适用ARM7

文章目录 一、ARM指令模拟器环境搭建1. keil软件2. Legacy Support 二、Keil仿真环境设置1. 创建一个项目2. 编译器介绍(1)arm-none-eabi-gcc(2)arm-none-linux-gnueabi-gcc(3)arm-eabi-gcc(4)grmcc(5)aarch64-linux-gnu-gcc 3. 安装编译器(1)设置调试 一、ARM指令模拟器环境搭…

StackOrQueueOJ3:用栈实现队列

目录 题目描述思路分析开辟队列入队列出队列 代码展示 题目描述 原题&#xff1a;232. 用栈实现队列 思路分析 有了前面的用队列实现栈的基础我们不难想到这题的基本思路&#xff0c;也就是用两个栈来实现队列&#xff0c;&#xff08;栈的实现具体参考&#xff1a;栈及其接口…