Java Set 不会重复?原来它有“记仇”的本事!

原文来自于:zha-ge.cn/java/43

Java Set 不会重复?原来它有"记仇"的本事!

前几天和同事聊天,忽然有人问: "为啥 Java 里的 Set,往里加东西,就是死活不让你重复?它心里到底咋想的?" 我一听,哈,这话题熟,讲起来比吐槽同事还顺!

Set 里的"记仇大法"

你想啊,Set,中文翻译就是"集合",但它跟"名单"可不一样。名单------随便写谁,重复也没人管。可 Java 的 Set,这可是一份"只能出现一次"的黑名单。你要是往里面塞重复的,Set 就跟个记仇精似的,死活认准你已经来过了。

为啥?其实本质上,Set 不是靠人品,靠的是底层的 hashCodeequals

  • 每次你往 Set 里丢个对象,它悄悄问自己俩问题:
    1. 这东西的 hashCode 跟别人一样吗?
    2. 如果 hashCode 一样,我还能用 equals 抖搂出真实身份吗?

只要发现"老熟人",它就直接甩锅说,喂,别进来了,等下一个吧。

代码片段来一眼

说到这儿,上点干货,给你看关键步骤:

java 复制代码
if (!set.contains(obj)) {
    set.add(obj);
}

嗯,JDK 底层其实比这个还复杂,但道理就是这么个意思。每加一个,都要"打卡登记"------否则,不让进。

踩坑瞬间

这东西好用归好用,我当年刚入职那会儿,却栽了个大跟头。

当时写了个 User 类,里面有 name 和 age,往 HashSet 里丢了一堆"看起来一模一样"的 user:

java 复制代码
User user1 = new User("小明", 11);
User user2 = new User("小明", 11);
set.add(user1);
set.add(user2);

我以为二选一,Set 肯定只留一个。结果一打印,两个都在!啊??怎么回事,这不是背叛了"不能重复"的信仰吗!

真相永远藏在 equals/hashCode

后来查了下,这才明白------ 原来自己写的 User 根本没覆写 equals 和 hashCode 啊!人家 Set 判断重复靠的就是这俩,你不写,它就只会比较引用(地址),user1 != user2,当然不当回事。

于是我灰溜溜补上:

java 复制代码
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    User user = (User) o;
    return age == user.age && Objects.equals(name, user.name);
}
// hashCode 也得覆盖!

这下,加多少"同款用户",Set 都只留一个了!

经验启示

别看 Set 冷酷,无情,其实它就是死认"你有没有本事自证身份"。用 Set 装自定义对象,千!万!记!得!

  • equals/hashCode 必须重写
  • List/数组要"包容",Set 要"守门"
  • 如果用的是 HashSet,hashCode 绝对是主要判断,TreeSet 则是 compareTo

我们程序员写类,有点像给对象办身份证。身份证号一换(equals/hashCode),Set 才认你。 要不然你每次都"离家出走换新衣服",它根本不认识你是谁!

以后见了 Set,可别只会往里塞,要让"黑名单"起作用,你得懂规则,否则老是掉进这个"重复元素不生效"的坑。

有啥用呢?去重嘛,统计嘛,社交App判好友......反正场景一大片!

行吧,今天就聊到这儿,这 Set 的"记仇大法"你可别再忘咯。哪天朋友问起,你也能一顿唠嗑吹回去嘿。

------ 代码就像生活,想不重复,可不容易 😊

相关推荐
掌心向暖RPA自动化2 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
日取其半万世不竭3 小时前
Minecraft Java版社区服务器搭建教程(Linux,适合新手)
java·linux·服务器
TeamDev3 小时前
JxBrowser 9.0.0 版本发布啦!
java·前端·混合应用·jxbrowser·浏览器控件·跨平台渲染·原声输入
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题】【Java基础篇】第24题:Java面向对象有哪些特征
java·开发语言·后端·面试
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题】【Java基础篇】第25题:JDK1.8的新特性有哪些
java·开发语言·后端·面试
likerhood4 小时前
SLF4J: Failed to load class “StaticLoggerBinder“ 解决
java·log4j·maven
早日退休!!!5 小时前
大模型推理瓶颈七层分析模型
java·服务器·数据库
叶小鸡5 小时前
Java 篇-项目实战-天机学堂(从0到1)-day9
java·开发语言
@#¥&~是乱码鱼啦5 小时前
Spring分层架构:Controller、Service、Mapper数据链路,IOC的真实工作意义
java·spring·架构
xieliyu.5 小时前
Java手搓数据结构:从零模拟实现无头双向非循环链表
java·数据结构·链表