java中的HashSet

news/2025/1/30 19:36:27/文章来源:https://www.cnblogs.com/ishoulgodo/p/18695297

什么是HashSet

在 Java 中,HashSet 是一个基于哈希表实现的集合类,它实现了 Set 接口
HashSet 的主要特点是:1,2

HashSet 的主要特点是

1,集合中的数据不能够重复
2,存储的数据是无序的(元素的存储顺序与插入顺序无关)
3,允许 null 值: 可以存储一个 null 元素(感觉这个不算)

HashSet 的常用方法

boolean add(e)向集合中添加元素。如果元素已存在,则返回 false。
boolean remove(Object o)从集合中移除指定元素。如果元素存在并成功移除,则返回 true。
boolean contains(Object o)检查集合中是否包含指定元素。如果存在,则返回 true。
int size() 返回集合中元素的数量。
boolean isEmpty()检查集合是否为空。如果为空,则返回 true。
void clear()清空集合中的所有元素。
Iterator iterator() 返回一个迭代器,用于遍历集合中的元素。
Object[] toArray() 将集合转换为数组。

hasSet存储为啥是无序的

hasSet 存储为啥数据不能够重复

hash存储是幂等性算法
也就是说:你给我一个A,计算出来的是2。
下次你再给一个A,计算出来的仍然是2。
这样的话,就会造成一个问题。
这个2要不要存储呢?
hasSet会丢弃第2个相同的值,因此存储的数据是不能够重复的。

存储数据是无序的

package part;
// HashSet在util这个包中,需要我们引入
import java.util.HashSet;
public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("赵6");// 输出的来是: [赵6, 李四, 张三] 说明存储数据是无序的System.out.println(setObject);}
}

存储的数据是不会重复的

public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("张三");// 输出的来是:System.out.println(setObject);}
}

HashSet如何修改数据

HashSet无法直接修改数据。
我们需要先把某一条要修改的数据删除掉。在新增我们想要的数据

package part;
// HashSet在util这个包中,需要我们引入
import java.util.HashSet;public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");// 把张三更改为张3,我们先删除然后再新增setObject.remove("张三");setObject.add("张3");// 输出: [李四, 张3]System.out.println(setObject);}
}

增强 for循环(也称为 for-each 循环) 来遍历数据

package part;
// HashSet在util这个包中,需要我们引入
import java.util.HashSet;
public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 我们通过特殊for循环来遍历数据for (Object o : setObject) {System.out.println(o);}}
}

增强 for循环的语法

for (元素类型 变量名 : 数组或集合) {// 循环体 // ps: 变量名是循环中的每一项
}

HashSet.add新增元素(如果元素已存在,则返回 false)

package part;
// HashSet在util这个包中,需要我们引入
import java.util.HashSet;
public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 输出的是 [李四, 张三, 王五]System.out.println(setObject);}
}

HashSet.addAll 将一个集合中的所有元素添加到另一个集合中

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();ArrayList<Integer> listObject = new ArrayList();listObject.add(1);listObject.add(2);LinkedList linkedListObject = new LinkedList();linkedListObject.add("张三");// 添加一个ArrayList集合对象setObject.addAll(listObject);// 添加一个LinkedList集合对象setObject.addAll(linkedListObject);// 输出的是: [1, 2, 张三]System.out.println("setObject:" + setObject);}
}

HashSet.toArray 将HashSet转化为数组

public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 将 HashSet 转换为数组Object obj = setObject.toArray();System.out.println(obj);}
}

HashSet.size() 获取HashSet 的长度

public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 获取HashSet 的长度int len = setObject.size();System.out.println(len);}
}

HashSet.clone 克隆

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 克隆HashSet,相当于复制了一份。但是我们需要使用Object来声明Object newSet = setObject.clone();}
}

克隆 HashSet 可以不用Object来声明吗?

克隆 HashSet 可以不用 Object 来声明吗? 可以的。
那为啥克隆需要使用 Object来声明呢?
因为:clone() 方法的返回类型是 Object。所以我们需要使用Object来声明。
我们可以使用强制转化来处理就行

public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 克隆HashSet,相当于复制了一份。我们可以使用强制转化来解决这个问题的HashSet newSet =(HashSet) setObject.clone();}
}

HashSet.remove(被移除的对象)

要从 HashSet 中移除的对象。如果 HashSet 包含该对象,则会被移除。
返回值是一个布尔值
如果 HashSet 中包含指定的对象并且成功移除,则返回 true。
如果 HashSet 中不包含该对象,则返回 false。

public class Java01 {public static void main(String[] args) {HashSet setObject = new HashSet();setObject.add("张三");setObject.add("李四");setObject.add("王五");// 移除李四Boolean delStatus = setObject.remove("李四");// 输出的是trueSystem.out.println(delStatus);}
}

ArrayList.remove根据传参不同,返回的类型不同

ArrayList arrList = new ArrayList();
arrList.add("嘿嘿01");
// 传参的是数字,返回的是被删除的数据
Object oldValue = arrList.remove(0);
public class Java01 {public static void main(String[] args) {ArrayList list = new ArrayList();list.add("A");// 传参字符串,返回来的是布尔Boolean flag = list.remove("A");System.out.println(flag);}
}

HashSet存储了相同的数据

package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;public class Java01 {public static void main(String[] args) {HashSet setList = new HashSet();User u1 = new User();User u2 = new User();u1.id = "2025_01_30";u1.name = "张三";u2.id = "2025_01_30";u2.name = "张三";setList.add(u1);setList.add(u2);// 大家认为会输出什么呢?// 输出的 [User [id=2025_01_30, name=张三], User [id=2025_01_30, name=张三]]System.out.println(setList);}
}class User{String id;String name;// ctrl + o 就可以啦 现在我重写了 toString@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + "]";}
}

不是说:HashSet中的数据不能重复吗?
为啥会重复呢?
因为:这2个对象在内存中是不同的地址哈~。
所以HashSet会认为是不同的值。
内存中是不同的地址我们一般认为是 hashCode不同(这种说法不准确,但是方便我们理解)
ps: hashCode类似与内存中的地址

解释为啥存储了相同的数据


package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;public class Java01 {public static void main(String[] args) {HashSet setList = new HashSet();User u1 = new User();User u2 = new User();u1.id = "2025_01_30";u1.name = "张三";u2.id = "2025_01_30";u2.name = "张三";setList.add(u1);setList.add(u2);// hashCode 我们可以理解为内存中的地址(这种说法不准确,但是方便我们理解)System.out.println(u1.hashCode()); // 685325104System.out.println(u2.hashCode()); // 460141958// 我们发现这2个地址不同,就会认为是2个不同的对象,就会出现相同的数据}
}class User{String id;String name;// ctrl + o 就可以啦@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + "]";}
}

如何如果让一个对象的id和name相同,就让它识别为是同一个数据

如果让一个对象的id和name相同,就让它识别为是同一个数据呢?
是可以的。我们需要重写2个方法;hashCode 和 equals
因为: HashSet是在存储数据的时候,就是通过hashCode来操作的。
我们给定一个值(字符串), 通过操作得到存储到哪一个位置。
当然不同的值可能得到的存储位置是一样的。
如果出现这样的情况,他会去比较他们的equals。
如果相等,会把这个数据(后面这个新增的数据)丢弃,什么都不做。
如果不相等,这个时候他会使用链表它装在一起哈。
我们也可以从这里得出结论:HashSet的底层是:数组+链表的结构来进行存储数据的

重写hashCode 和 equals


package part;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;public class Java01 {public static void main(String[] args) {HashSet setList = new HashSet();User u1 = new User();User u2 = new User();u1.id = 2025;u1.name = "张三";u2.id = 2025;u2.name = "张三";setList.add(u1);setList.add(u2);// [User [id=2025, name=张三]] 现在数据就不会重复了System.out.println(setList);}
}class User{int id;String name;//    重写方法的快捷键 ctrl+o@Override//  类似与我们的内存地址,我们使用id来判断public int hashCode() {return id;}@Override// 判断2个对象的属性是否完全相同public boolean equals(Object obj) {if(obj instanceof User) {//因为这个对象是User类型的,我们可以使用强制转换User u = (User)obj;//判断对象的属性是否相同,这里为啥使用equals,等会回说一下if(u.id==this.id && u.name.equals(this.name)) {return true;}else{return false;}}else{// 如果不是,直接返回falsereturn false;}}@Overridepublic String toString() {return "User [id=" + id + ", name=" + name + "]";}
}

HashSet的底层是:数组+链表的结构来进行存储数据的

== 和 equals的区别

1,当使用 == 比较基本数据类型,它比较的是两个变量的值是否相等。
2,当使用 == 比较引用数据类型(如对象)时,它比较的是对象的内存地址是否相等,即它们是否引用同一内存地址。
3,equals是Object类中的一个方法,用于比较同一类的两个对象的内容是否相等。

equals的比较逻辑

equals方法首先检查两个对象是否为同一类的实例(即类是否相等)。
如果不属于同一类,则对象肯定不相等。
如果类相等,equals方法将逐一比较两个对象的字段或属性,以确定它们是否相等。

尾声

准备开始学习java了。
今天学习的第三天,每天都会发文章,我要卷起来。
请小伙伴们监督我,奥利给

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

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

相关文章

记录本地部署自己的DeepSeek 大模型AI

准备工具Ollama:用于简化大型语言模型(LLM)的本地部署和使用,可以同时支持多个大模型,开发者能够方便地在本地环境中运行和测试不同的语言模型,简单的说就是相当于一个容器。官网地址:https://ollama.com/ChatBox AI:是一款用于接入各种大模型的客户端,使在大模型AI时…

CF999

A link首先,每次操作(第一次除外)之前\(s\)一定是一个奇数,那么我们要再加一个奇数才能让它变为偶数分数加一。 那么就是说操作过至少一次后,有几个奇数就有几分。 那么如果有至少一个偶数,那么第一次用偶数可以得分,后面再用奇数可以得分,偶数的不了分,最终得分就是奇…

1.30

1.30 Maze - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)从一个空格走cnt - k个点并标记,然后将没有标记的点设为A即可import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputS…

java中jdk的下载地址

java中jdk的下载地址 https://www.oracle.com/java/technologies/downloads/#java17-windows作者:流年少年 出处:https://www.cnblogs.com/ishoulgodo/ 想问问题,打赏了卑微的博主,求求你备注一下的扣扣或者微信;这样我好联系你;(っ•̀ω•́)っ✎⁾⁾!如果觉得这篇文章…

对国外某网站的SQL注入实战

对国外某网站的SQL注入实战 记录一次某功能点遇到SQL注入漏洞尝试丢到SQLMAP运行虽然成功,但是有些SQL注入类型存在但SQLMAP未识别出来,随后便使用手工注入的方式获得数据库相关数据的随笔 功能点某网站存在URL如下的GET形公告展示点: /xxx/index.php?mod=detail&_id=23…

@所有Mac用户 刺客信条系列登陆Mac平台!

🌟【历史性的跨越】🌟 在无数Mac游戏爱好者的热切期盼中,终于将风靡全球的3A级巨作——刺客信条🌟【历史性的跨越】🌟 在无数Mac游戏爱好者的热切期盼中,终于将风靡全球的3A级巨作——刺客信条系列,成功移植至MacOS系统!这意味着,无论是穿梭于中世纪欧洲的隐秘巷弄…

五、USB PD协议层之控制消息

当Message Header中的Number of Data Objects字段设置为0,控制消息仅由一个Message Header和一个CRC组成。协议层发起控制消息(如,Accept Message, Reject Message 等)。 控制消息类型在消息头的Message Type字段(位4…0)中指定,并汇总在下表中。1、GoodCRC Message Good…

htb support walkthrough window 域渗透

nmap udp端口 nmap -sU 10.10.11.174 Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-30 01:17 UTC Nmap scan report for 10.10.11.174 Host is up (0.092s latency). Not shown: 996 open|filtered udp ports (no-response) PORT STATE SERVICE 53/udp open domai…

01 设计测试用例

设计测试用例的万能思路 针对某个物品/功能进行测试。 万能思路:功能测设 + 界面测试 + 性能测试 + 兼容性测试 + 易用性测试 + 安全测试。总结: 功能测试: 水杯:装水、喝水... 注册场景:注册 + 登录 ​ 想象日常使用中的注册场景有哪些功能。 界面测试: 非软件:颜色…

C++ 实现一个vector

C++如何写一个带有allocator的vector 在STL中,容器一般都有一个allocator模板参数。 allocator用于获取/释放内存及构造/析构内存中元素的分配器。类型必须满足分配器 (Allocator) 。如果 Allocator::value_type 与 T 不同,那么行为未定义(C++20 前)程序非良构(C++20 起)。 模…

使用xtrabackup对MySQL8.0.34进行备份和恢复

Percona XtraBackup 是一款开源的、用于 MySQL 和 MariaDB 的热备份工具,它可以在不停止数据库服务的情况下进行全量或增量备份,并且能够快速恢复数据。以下从特点、安装、备份与恢复操作、注意事项等方面进行详细介绍。 特点热备份:可以在数据库正常运行时进行备份,不影响…

【THM】Search Skills(搜索技巧)-学习

学习有效地搜索互联网并使用专门的搜索引擎和技术文档。本文相关的TryHackMe实验房间链接:https://tryhackme.com/r/room/searchskills 本文相关内容:学习有效地搜索互联网并使用专门的搜索引擎和技术文档。介绍 在 Google 上快速搜索“学习网络安全-learn cyber security”返…