要让java的hashset正确避免元素重复,核心在于必须正确重写hashcode()和equals()方法。1. 自定义类必须同时重写hashcode()和equals()方法,否则hashset无法识别逻辑上相同的对象为重复;2. equals()方法需满足自反性、对称性、传递性、一致性和与null比较返回false的契约;3. hashcode()必须保证:如果两个对象equals为true,则它们的hashcode必须相等;4. 应使用相同的字段参与hashcode()和equals()的计算;5. 用于计算hashcode()和equals()的字段应尽量保持不可变,或在对象加入hashset后不再修改,否则会导致哈希码变化,使对象“丢失”在原桶中,造成查找失败、幽灵元素或重复添加等问题;6. 正确的做法是:若需修改关键字段,应先从hashset中移除对象,修改后再重新添加。只有遵循这些原则,hashset才能正确维护元素唯一性并保证性能。

要让Java的
HashSet
hashCode()
equals()
HashSet
HashSet
HashSet
hashCode()
equals()
hashCode()
equals()
HashSet
这意味着,如果你想让
HashSet
Person
Person
hashCode()
equals()
立即学习“Java免费学习笔记(深入)”;
x
x.equals(x)
true
x
y
x.equals(y)
true
y.equals(x)
true
x
y
z
x.equals(y)
true
y.equals(z)
true
x.equals(z)
true
x
y
equals
x.equals(y)
x
x.equals(null)
false
hashCode
equals
hashCode()
equals
通常,IDE(如IntelliJ IDEA或Eclipse)都提供了自动生成
hashCode()
equals()
import java.util.HashSet;
import java.util.Objects; // Java 7+ 提供了Objects.hash()和Objects.equals()简化实现
public class MyObject {
private int id;
private String name;
public MyObject(int id, String name) {
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
@Override
public boolean equals(Object o) {
// 检查是否是同一个对象引用
if (this == o) return true;
// 检查是否为null或类型不匹配
if (o == null || getClass() != o.getClass()) return false;
// 类型转换
MyObject myObject = (MyObject) o;
// 比较关键字段
return id == myObject.id &&
Objects.equals(name, myObject.name); // 使用Objects.equals处理null安全
}
@Override
public int hashCode() {
// 使用Objects.hash()生成哈希码,它能处理null字段
return Objects.hash(id, name);
}
@Override
public String toString() {
return "MyObject{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public static void main(String[] args) {
HashSet<MyObject> set = new HashSet<>();
MyObject obj1 = new MyObject(1, "Alice");
MyObject obj2 = new MyObject(2, "Bob");
MyObject obj3 = new MyObject(1, "Alice"); // 逻辑上与obj1相同
set.add(obj1);
System.out.println("添加obj1: " + set.size()); // 1
set.add(obj2);
System.out.println("添加obj2: " + set.size()); // 2
set.add(obj3); // 尝试添加逻辑上重复的obj3
System.out.println("添加obj3: " + set.size()); // 仍然是2,因为obj3被识别为重复
System.out.println("Set内容: " + set);
System.out.println("Set是否包含obj1: " + set.contains(obj1)); // true
System.out.println("Set是否包含obj3: " + set.contains(obj3)); // true
}
}hashCode()
equals()
HashSet
说起来,
HashSet
当你调用
add()
HashSet
hashCode()
HashSet
HashSet
HashSet
equals()
但是,不同的对象可能会计算出相同的哈希码,这叫做“哈希冲突”。就像你可能有两个不同的文件,它们的校验和(哈希值)碰巧一样。当发生哈希冲突时,
HashSet
equals()
HashSet
equals()
equals()
true
HashSet
所以,
hashCode()
equals()
hashCode()
HashSet
equals()
ArrayList
HashSet
equals()
HashSet
HashSet
当你把自定义类的实例放进
HashSet
hashCode()
equals()
HashSet
一个常见的误区是,只重写了
equals()
hashCode()
equals()
hashCode()
Object
hashCode()
HashSet
HashSet
另一个重要的点是,用于计算
hashCode()
equals()
HashSet
hashCode()
equals()
HashSet
HashSet
举个例子,如果你的
Person
age
hashCode()
equals()
age
Person
HashSet
Person
age
Person
HashSet
age
Person
contains()
remove()
HashSet
age
所以,最佳实践是,如果你要将对象放入
HashSet
HashSet
这绝对是一个会让你头疼的问题,因为它会导致
HashSet
正如前面提到的,
HashSet
hashCode()
HashSet
hashCode()
hashCode()
想象一下这个场景:你有一个
Person
p
id
name
add
HashSet
HashSet
p
p
id
p
hashCode()
问题来了:
p
contains(p)
remove(p)
HashSet
p
hashCode()
p
HashSet
contains()
false
remove()
p
HashSet
Person
id
name
p
HashSet
HashSet
p
HashSet
HashSet
HashSet
所以,这是一个非常重要的规则:不要在对象被添加到HashSet
hashCode()
equals()
HashSet
HashSet
HashSet
HashSet
以上就是Java集合框架如何避免HashSet的元素重复问题_Java集合框架哈希集合的使用教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号