目录
在 Java 中,HashSet
的底层依赖于 HashMap
,通过 对象的 hashCode()
值和 equals()
方法 来判断是否为重复数据。如果添加的数据已经存在(即 hashCode()
和 equals()
返回一致),则不会将其添加到 HashSet
中。
判断是否为相同数据的原理
hashCode()
:- 用于快速定位数据存储的桶(bucket)。
- 如果两个对象的
hashCode()
不同,则直接认为数据不同。
equals()
:- 如果
hashCode()
相同,则进一步用equals()
判断是否真的相同。 - 如果
equals()
返回true
,则表示数据相同。
- 如果
示例代码
以下代码展示如何用 HashSet
判断是否为重复数据:
import java.util.HashSet;
public class Main {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
// 添加数据
System.out.println("添加 'apple': " + hashSet.add("apple")); // 返回 true, 数据被添加
System.out.println("添加 'banana': " + hashSet.add("banana")); // 返回 true, 数据被添加
System.out.println("添加 'apple': " + hashSet.add("apple")); // 返回 false, 数据已存在
// 输出 HashSet 中的数据
System.out.println("当前 HashSet 内容: " + hashSet);
// 检查数据是否存在
String item = "apple";
if (hashSet.contains(item)) {
System.out.println(item + " 已存在于 HashSet 中");
} else {
System.out.println(item + " 不在 HashSet 中");
}
}
}
自定义对象的判断
如果是自定义类对象,需要重写 hashCode()
和 equals()
方法,否则即使内容相同,默认按内存地址比较,结果会认为是不同数据。
示例代码:
import java.util.HashSet;
import java.util.Objects;
class Person {
String name;
int age;
public 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);
}
@Override
public String toString() {
return "Person{name='" + name + "', age=" + age + '}';
}
}
public class Main {
public static void main(String[] args) {
HashSet<Person> people = new HashSet<>();
// 添加自定义对象
Person p1 = new Person("Alice", 25);
Person p2 = new Person("Bob", 30);
Person p3 = new Person("Alice", 25); // 与 p1 数据相同
System.out.println("添加 p1: " + people.add(p1)); // 返回 true
System.out.println("添加 p2: " + people.add(p2)); // 返回 true
System.out.println("添加 p3: " + people.add(p3)); // 返回 false, 数据重复
// 输出 HashSet 内容
System.out.println("当前 HashSet 内容: " + people);
}
}
输出示例:
添加 p1: true
添加 p2: true
添加 p3: false
当前 HashSet 内容: [Person{name='Alice', age=25}, Person{name='Bob', age=30}]
总结
- 简单类型:
HashSet
通过hashCode()
和equals()
自动判断重复数据。 - 自定义类型:需要重写
hashCode()
和equals()
方法,否则默认按引用地址判断是否重复。