0

0

在Java里Set集合为什么不能存重复值_Java集合唯一性原理说明

P粉602998670

P粉602998670

发布时间:2026-01-29 10:29:06

|

323人浏览过

|

来源于php中文网

原创

Set去重逻辑取决于具体实现:HashSet依赖hashCode()和equals()一致性判断重复,TreeSet则依赖compareTo()或Comparator返回0来判定重复,二者语义可能不一致。

在java里set集合为什么不能存重复值_java集合唯一性原理说明

Set 的重复值判断依赖于 equals()hashCode()

Java 中 Set 接口本身不规定去重逻辑,真正起作用的是它的具体实现类(如 HashSetTreeSetLinkedHashSet)。其中最常用的是 HashSet,它底层用 HashMap 存储元素 —— 把元素作为 key,固定对象 PRESENT 作为 value。所以“不能存重复值”的本质,是 HashMap.put() 拒绝插入相同 key 的行为。

HashMap 判断 key 是否相同,分两步:

  • 先比 hashCode():如果两个对象的 hashCode() 不同,直接认为不相等;
  • 再比 equals():只有 hashCode() 相同,才会调用 equals() 进一步确认。

这意味着:如果你自定义类放进 HashSet,但没重写 equals()hashCode(),那默认用的是 Object 的实现(基于内存地址),即使两个对象内容完全一样,也会被当作不同元素存入。

TreeSet 的去重逻辑完全不同:靠 compareTo()Comparator

TreeSet 底层是红黑树,不依赖 hashCode(),而是依赖元素的自然顺序或外部比较器。它用 Comparable.compareTo()(或 Comparator.compare())返回值是否为 0 来判断“重复”。

立即学习Java免费学习笔记(深入)”;

也就是说:TreeSet 认为两个元素重复,当且仅当 compare(a, b) == 0(或 a.compareTo(b) == 0)。这和 HashSet 的语义可能不一致 —— 比如你重写了 equals() 但没实现 Comparable,或者 compareTo() 的逻辑和 equals() 不一致,就可能出现“HashSet 觉得不重复,TreeSet 却只留一个”的情况。

常见错误示例:

Toolplay
Toolplay

一站式AI应用聚合生成平台

下载
class Person {
    String name;
    int age;
    Person(String name, int age) { this.name = name; this.age = age; }
    // 忘记重写 equals/hashCode → HashSet 会存多个相同内容对象
    // 也没实现 Comparable → TreeSet 会抛 ClassCastException
}

添加失败时不会报错,只是静默忽略

Set.add() 方法返回 boolean:成功添加返回 true,发现重复则返回 false,**不会抛异常**。很多人误以为“加不进去是 bug”,其实是正常行为。

容易踩的坑包括:

  • new Integer(1)new Integer(1) 测试 HashSet,发现能去重 —— 这是因为 Integer 正确实现了 equals()hashCode()
  • 换成 new Object() 试,发现两个新 Object 实例都能加进去 —— 因为它们的 hashCode() 不同(地址不同),equals() 也返回 false
  • 在循环里反复 set.add(x) 却没检查返回值,误以为每次都新增了数据。

唯一性不是“值相等”,而是“逻辑相等”的约定结果

所谓“不能存重复值”,其实是个契约:你告诉集合“哪些对象算一样”,集合才据此执行去重。这个契约由你提供的 equals()/hashCode()compareTo() 定义。Java 不做任何智能推断。

最常被忽略的一点是:hashCode()equals() 必须保持一致性 —— 如果两个对象 equals() 返回 true,它们的 hashCode() **必须相同**;反之不强制。违反这点会导致 HashSet 行为异常(比如该找到的元素找不到)。

复杂点在于:这个契约一旦定下,就不能随意改。比如把 PersonhashCode() 基于 name,后来又想按 name + age 判断相等,就必须同步更新两个方法,否则已有数据在集合里的位置就乱了。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
java中boolean的用法
java中boolean的用法

在Java中,boolean是一种基本数据类型,它只有两个可能的值:true和false。boolean类型经常用于条件测试,比如进行比较或者检查某个条件是否满足。想了解更多java中boolean的相关内容,可以阅读本专题下面的文章。

350

2023.11.13

java boolean类型
java boolean类型

本专题整合了java中boolean类型相关教程,阅读专题下面的文章了解更多详细内容。

29

2025.11.30

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1130

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

213

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1741

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

20

2026.01.19

clawdbot ai使用教程 保姆级clawdbot部署安装手册
clawdbot ai使用教程 保姆级clawdbot部署安装手册

Clawdbot是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

15

2026.01.29

clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址
clawdbot龙虾机器人官网入口 clawdbot ai官方网站地址

clawdbot龙虾机器人官网入口:https://clawd.bot/,clawdbot ai是一个“有灵魂”的AI助手,可以帮用户清空收件箱、发送电子邮件、管理日历、办理航班值机等等,并且可以接入用户常用的任何聊天APP,所有的操作均可通过WhatsApp、Telegram等平台完成,用户只需通过对话,就能操控设备自动执行各类任务。

12

2026.01.29

Golang 网络安全与加密实战
Golang 网络安全与加密实战

本专题系统讲解 Golang 在网络安全与加密技术中的应用,包括对称加密与非对称加密(AES、RSA)、哈希与数字签名、JWT身份认证、SSL/TLS 安全通信、常见网络攻击防范(如SQL注入、XSS、CSRF)及其防护措施。通过实战案例,帮助学习者掌握 如何使用 Go 语言保障网络通信的安全性,保护用户数据与隐私。

8

2026.01.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 3万人学习

C# 教程
C# 教程

共94课时 | 7.8万人学习

Java 教程
Java 教程

共578课时 | 52.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号