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 的"记仇大法"你可别再忘咯。哪天朋友问起,你也能一顿唠嗑吹回去嘿。

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

相关推荐
爱吃山竹的大肚肚7 分钟前
文件上传大小超过服务器限制
java·数据库·spring boot·mysql·spring
黄昏恋慕黎明8 分钟前
测试模型讲解
java
瑞雪兆丰年兮10 分钟前
[从0开始学Java|第十二天]学生管理系统升级
java·开发语言
弹简特10 分钟前
【JavaSE-网络部分03】网络原理-泛泛介绍各个层次
java·开发语言·网络
周杰伦的稻香11 分钟前
Hexo搭建教程
java·node.js
倔强的石头10611 分钟前
飞算JavaAI如何提升重塑Java开发体验
java·飞算javaai·ai开发工具
努力d小白14 分钟前
leetcode438.找到字符串中所有字母异位词
java·javascript·算法
短剑重铸之日14 分钟前
《设计模式》第九篇:三大类型之结构型模式
java·后端·设计模式·组合模式·代理模式·结构性模式
没有bug.的程序员16 分钟前
RocketMQ 与 Kafka 深度对垒:分布式消息引擎内核、事务金融级实战与高可用演进指南
java·分布式·kafka·rocketmq·分布式消息·引擎内核·事务金融
jiang_changsheng17 分钟前
工作流agent汇总分析 2
java·人工智能·git·python·机器学习·github·语音识别