You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

属性相同的两个Java类,equals生效但List.contains为何返回false?

List.contains()返回false但equals()返回true的原因及解决方案

核心原因:List.contains()的比较方向与equals对称性缺失

Java中List.contains(Object o)的底层逻辑是遍历集合元素,调用传入参数o的equals()方法和集合中的元素逐一比较,而非反过来用集合元素的equals()去匹配参数。

你的场景中:

  • RelocationDisabledProduct重写了equals(),可以识别Item类型对象,属性相同时返回true(即relocationDisabledProduct.equals(item)为true)
  • 但Item类的equals()未处理RelocationDisabledProduct类型对象——要么没重写(使用Object默认的引用比较),要么重写后仅判断同类型的Item,导致item.equals(relocationDisabledProduct)返回false

当调用list.contains(item)时,集合会用item.equals(集合中的RelocationDisabledProduct元素)做比较,结果全为false,最终contains()返回false。

解决方案

方案1:修复equals的对称性

根据Java的equals规范,若a.equals(b)为true,则b.equals(a)必须也为true(对称性要求)。因此需要修改Item类的equals()方法,让它能识别RelocationDisabledProduct类型对象,属性相同时返回true。

同时要同步修改hashCode()方法,确保属性相同的Item和RelocationDisabledProduct返回相同哈希值(否则HashSet、HashMap等哈希集合会出现异常)。

示例代码:

// Item类的equals和hashCode重写
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null) return false;
    // 同时兼容Item和RelocationDisabledProduct类型
    if (o instanceof Item) {
        Item that = (Item) o;
        return Objects.equals(this.getId(), that.getId());
    } else if (o instanceof RelocationDisabledProduct) {
        RelocationDisabledProduct that = (RelocationDisabledProduct) o;
        return Objects.equals(this.getId(), that.getId());
    }
    return false;
}

@Override
public int hashCode() {
    return Objects.hash(getId()); // 仅用共同属性计算哈希值
}

方案2:转换类型后调用contains

如果无法修改Item类代码,可以将Item对象转换为RelocationDisabledProduct对象后,再传入contains()方法:

// 同步Item的属性到RelocationDisabledProduct对象
RelocationDisabledProduct converted = new RelocationDisabledProduct();
converted.setId(item.getId());
// 其他属性逐一同步赋值
boolean exists = list.contains(converted);

内容的提问来源于stack exchange,提问作者arlen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:55:22