Java覆盖equals函数的技巧

9 篇文章 0 订阅

为什么要覆盖equals函数

Object对象自带equals方法,但其是根据对象是否一致来判断相等,但每个对象都是唯一的,所以自带的equals方法只能与其自身相等。
当需要根据对象的成员值是否相等来判断对象是否相等时,就需要复写equals函数了。

equals函数需要遵循的原则

  • 自反性
    x.equals(x) == true
  • 对称性
    x.equals(y) == y.equals(x);
  • 传递性
    x.equals(y) == y.equals(z) == x.equals(z);
  • 一致性
  • 非空性
    在属性没有被修改时,
    x.equals(y)的值不应该会发生改变。

常见错误

1.违反对称性
public final class CaseInsensitiveString{
    private final String s;
    public CaseInsensitiveString(String s){
        if(s == null)
            throw new NullPointerException();
        this.s = s;
    }
    @Override
    public boolean equals(Object o){
        if(o instanceof CaseInsensitiveString)
            return s.equalsIgnoreCase(((CaseInsensitiveString) o).s);
        if (o instanceof String)
            return s.equalsIgnoreCase((String) o);
        return false;
    }
    ......
}

以上equals方法在

CaseInsensitiveString cs = new CaseInsensitiveString("a");
String s = "a";

cs.equals(s);// true
s.equals(cs);// false

解决方法是去掉与String交互那部分

    @Override
    public boolean equals(Object o){
        if(o instanceof CaseInsensitiveString)
            return s.equalsIgnoreCase(((CaseInsensitiveString) o).s);
        return false;
    }
2.违反传递性
public class Point{
    public int x;
    public int y;
    ........
    @Override
    public boolean equals(Object o){
        if( !(o instanceof  Point))
            return false;
        if(o.x == x && o.y == y)
            return true;
        return false;
    }
}

增加颜色属性

public class ColorPoint extends Point{
    public int color;
    .....
    @Override
    public boolean equals(Object o){
        if(!(o instanceof Point))
            return false;
        if(!(o instanceof ColorPoint)
            return o.equals(this);
        return super.equals(o) && ((ColorPoint)o).color == color;

}

以上代码,虽然保证了对称性,但传递性有错误

ColorPoint p1 = new ColorPoint(1,2,1);
Point p2 = new Point(1,2);
ColorPoint p3 = new ColorPoint(1,2,2);
p1.equals(p2)//true
p2.equals(p3)//true
p1.equals(p3)/false

解决方案:通过复合替代继承,并放弃混合比较

public class ColorPoint{
    public Point poin;
    public int color;
    public Point asPoint(){
        return point;
    }
    @Override
    public boolean equals(Object o ){
        if(!(o instanceof ColorPoint))
            return false;
        return (ColorPoint)o.point.equals(point) && (ColorPoint)o.color == color;
    }
}
3.非空性

如果不做处理可能会报出空指针错误

@Override
public boolean equals(Object o){
    if( o == null)
        return false;
}
4.注意事项

复写equals方法的同时,一定要复写hashCode方法,不然会导致HashMap等涉及到哈希数据结构的错误。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值