在 Java 中,Set 集合去重的原理本质上依赖于两个方法:hashCode() 和 equals()。不同实现类(如 HashSet、LinkedHashSet、TreeSet)在细节上略有差异,但核心思想一致。
HashSet 的去重原理Set 判断两个元素是否重复,先比较
hashCode(),再比较equals()。
当你调用:
set.add(obj);
HashSet 内部会做以下事情:
int hash = obj.hashCode();
equals() 逐个比较equals 返回 true → 认为是重复元素,不加入equals 都返回 false → 加入✅ 只有 hashCode 相同 且 equals 为 true,才算重复
equals() 逐个比较Set<String> set = new HashSet<>();
set.add("abc");
set.add("abc");
System.out.println(set.size()); // 1
原因:
String 重写了 hashCode() 和 equals()class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Set<Person> set = new HashSet<>();
set.add(new Person("张三", 18));
set.add(new Person("张三", 18));
System.out.println(set.size()); // 2 ❌ 没去重
hashCode() 和 equals()Object 的方法class Person {
String name;
int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person p = (Person) o;
return age == p.age && Objects.equals(name, p.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
此时:
set.size(); // 1 ✅
TreeSet 的去重原理(另一种)TreeSet 不使用 hashCode 和 equals,而是使用:
Comparable 或 ComparatorSet<Integer> set = new TreeSet<>();
set.add(3);
set.add(3);
判断重复规则:
compareTo() 返回 0 → 认为是相同元素⚠️ 注意:
compareTo() == 0 必须和逻辑相等一致| Set 类型 | 去重依据 | 是否依赖 hashCode |
|---|---|---|
| HashSet | hashCode + equals | ✅ 是 |
| LinkedHashSet | hashCode + equals | ✅ 是 |
| TreeSet | compareTo / compare | ❌ 否 |
HashSet 去重:先 hashCode 定位,再 equals 判断;
TreeSet 去重:compareTo 返回 0 就是重复。
如果你愿意,我也可以帮你画一张 HashSet 底层结构图 或结合 面试高频问法 给你总结。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。