重写equals/hashCode后ArrayList.contains仍返回false问题求助
问题根源与修复方案
你的问题出在SpotResponse类的equals方法实现上——你用了==来比较id字符串,这在Java里是个常见的坑!
为什么会这样?
- Java中
==对于引用类型(比如String),比较的是对象的内存地址,而不是字符串的实际内容。只有当两个String是同一个对象(或者是字符串常量池里的相同字面量)时,==才会返回true。如果oldSpot的id和newSpots里对象的id是内容相同但不同的String对象,==就会返回false,导致contains判断失败。 - 而
newKeys.contains(oldSpot.getId())能正常工作,是因为List的contains方法对于String类型,调用的是String自己的equals方法——它是比较字符串内容的,所以只要内容匹配就会返回true。
修复代码
把equals方法里的字符串比较改成用Objects.equals()(它会自动处理null的情况,避免空指针异常):
@Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SpotResponse that = (SpotResponse) o; // 替换成Objects.equals比较内容 return Objects.equals(id, that.id); }
同时,为了保证hashCode和equals的一致性(这是Java规范的要求),建议把hashCode也改成用Objects.hashCode():
@Override public int hashCode() { return Objects.hashCode(id); }
修复后效果
修改完成后,newSpots.contains(oldSpot)就会根据id的实际内容来判断是否包含目标对象,和你用String列表判断的结果完全一致了。
内容的提问来源于stack exchange,提问作者ntakouris
相关产品推荐
相关产品推荐

