Java HashSet重复对象添加问题:为何属性相同的Car实例被重复加入?
HashSet添加重复元素问题排查与解决
问题原因
你已经命中了核心问题:没有正确重写equals方法。Java中Object类定义的equals方法签名是public boolean equals(Object obj),你写的public boolean equals(Car c)只是重载而非重写该方法。HashSet判断元素重复时,只会调用Object类规定的equals(Object)方法,你重载的Car参数版本完全不会被触发。
即便a和b的hashCode相同,HashSet仍会通过equals做最终校验。由于你没重写equals(Object),默认使用Object类的实现——比较对象内存地址。a和b是两个独立实例,内存地址不同,所以HashSet判定它们是不同元素,允许第二次添加。
解决方案
正确重写equals方法,同时遵循Java规范:重写equals必须同步重写hashCode(确保相等的对象拥有相同hashCode,不等对象尽量拥有不同hashCode)。
修改后的Car类方法示例:
import java.util.Objects; public class Car { private String brand; private String model; private int version; // 构造方法、getter/setter省略 @Override public boolean equals(Object obj) { // 引用相同直接返回true if (this == obj) return true; // 对象为空或类型不匹配返回false if (obj == null || getClass() != obj.getClass()) return false; // 类型转换后逐一比较字段 Car car = (Car) obj; return version == car.version && brand.equals(car.brand) && model.equals(car.model); } @Override public int hashCode() { // 基于字段组合生成hashCode,保证equals相等的对象hashCode一致 return Objects.hash(brand, model, version); } }
修改后运行测试代码,hash.add(b)会返回false,集合中只会保留一个元素,符合预期。
内容的提问来源于stack exchange,提问作者Sergio Obici
相关产品推荐
相关产品推荐

