Java重写equals时集合contains问题

当在Java中重写equals方法时,未遵循对称性原则可能导致集合contains方法返回异常结果。文章通过一个问题场景解释了这个问题,并指出解决此问题需要确保equals方法的自反性、对称性、传递性、一致性和空引用性质。解决方案是为子类单独实现equals方法,避免使用instanceof关键字。

问题

  在父类中重写了equals方法,将父类对象添加进list中并且不存在子类对象时,调用list.contains(子类)返回true,反之亦然。

结论

重写equals时要考虑以下原则:

  • 自反性:非空引用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引用对象没有改变,则反复调用x.equals(y)应返回相同值。
  • 空引用:x.equals(null) 应返回false

上述问题是因为没考虑“对称性”原则,子类会继承父类equals方法,因此无论父类.equals(子类)还是子类.equals(父类)都是true。

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

class A {
    public String obj;
    public String name;
    public A(String obj, String name) {
        this.obj = obj;
        this.name = name;
    }
    public int id = 1;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;  // 自反性
        if (!(o instanceof A)) return false;
        A a = (A) o;
        return Objects.equals(obj, a.obj);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, id);
    }
}

class B extends A{
    public B(String obj, String name) {
        super(obj, name);
    }
}

public class Test {
    public static void main(String[] args) {
        A a1 = new A("a", "a");
        A a2 = new B("a", "a");
        List<A> list = new ArrayList<>();
        list.add(a2);
        System.out.println(list.contains(a1));
    }
}
结果

运行结果

修改思路

  • 重写子类equals方法,使用o instanceof 子类来与自身判断
  • 父类中不使用instaceof,改为
    if (o == null || getClass() != o.getClass()) return false;
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值