HashSet自动去重,基于HashMap实现,依赖hashCode()和equals()判断唯一性;自定义类须重写这两方法,否则逻辑相等对象可能重复添加。

Java 中 HashSet 本身就是为存储**不重复元素**而设计的集合,添加时自动去重,不需要手动判断。它的底层基于 HashMap 实现,利用对象的 hashCode() 和 equals() 方法来保证唯一性。
添加元素自动去重的原理
HashSet.add(E e) 方法返回 boolean:
- 如果元素 不存在,则添加成功,返回
true; - 如果元素 已存在(根据
equals()+hashCode()判定),则不添加,返回false。
关键前提是:自定义类必须正确重写 hashCode() 和 equals() 方法,否则即使逻辑上相等的对象也可能被重复添加。
基本用法示例
添加字符串、数字等内置类型(已重写好方法):
立即学习“Java免费学习笔记(深入)”;
Set<String> set = new HashSet<>();
set.add("apple"); // true
set.add("banana"); // true
set.add("apple"); // false,未添加,集合不变
System.out.println(set); // [banana, apple](顺序不保证)
自定义类必须重写 hashCode 和 equals
例如有一个 Person 类:
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
// 必须重写!否则两个同名同年的人会被视为不同对象
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
这样使用才有效:
-
set.add(new Person("Alice", 25))→ 添加成功 -
set.add(new Person("Alice", 25))→ 返回false,不重复添加
常见误区提醒
-
不要依赖插入顺序:HashSet 不保证顺序,如需有序,请用
LinkedHashSet;如需排序,用TreeSet。 -
null 元素允许且唯一:最多只能存一个
null,多次add(null)只有第一次生效。 -
线程不安全:多线程环境下需额外同步,或改用
Collections.synchronizedSet(new HashSet<>())或ConcurrentHashMap.newKeySet()。


















