ArrayList存储自定义对象去重失败:contains方法失效问题排查
问题原因与解决方案
问题根源
你定义的Archive类中的equals方法是重载而非重写Object类的equals方法。ArrayList的contains方法底层调用的是Object类的equals(Object obj),而你写的equals(Archive obj)是一个全新的方法,并没有覆盖父类的逻辑。因此contains依然使用默认的引用比较(判断两个对象是否是同一个内存地址),导致即使identifier相同的不同对象,也会被判定为不相等,从而重复添加到集合中。
解决方案
正确重写Object类的equals方法,同时按照Java规范重写hashCode方法(虽然ArrayList的contains不依赖hashCode,但后续使用哈希集合时必须保证两者一致):
修改后的Archive类代码:
public class Archive { private String identifier; private String name; public Archive(String id, String name) { this.identifier = id; this.name = name; } public String id() { return this.identifier; } public String name() { return this.name; } @Override public boolean equals(Object o) { // 引用相同直接返回相等 if (this == o) return true; // 对方为null或类型不匹配,返回不相等 if (o == null || getClass() != o.getClass()) return false; // 转换为Archive类型后比较identifier Archive archive = (Archive) o; // 处理identifier为null的情况,避免空指针异常 return identifier != null ? identifier.equals(archive.identifier) : archive.identifier == null; } @Override public int hashCode() { // 基于identifier生成哈希值,与equals逻辑保持一致 return identifier != null ? identifier.hashCode() : 0; } }
关键说明
@Override注解:强制检查是否正确重写了父类方法,避免因参数类型错误导致的重载问题。- 空值处理:在比较
identifier时先判断是否为null,防止调用equals时抛出NullPointerException。 hashCode重写:遵循Java对象约定,确保equals返回true的两个对象,其hashCode值一定相等,避免后续使用哈希集合时出现逻辑错误。
内容的提问来源于stack exchange,提问作者Nihilo Diem
相关产品推荐
相关产品推荐

