庄生晓梦

庄生晓梦迷蝴蝶

博客园 首页 新随笔 联系 订阅 管理
  164 随笔 :: 3 文章 :: 1 评论 :: 74038 阅读

覆盖equals是要遵守的约定

1.覆盖种类:
-类的每个1实例本质上都是唯一的
-不关心类是否提供了”逻辑相等”的测试功能(Random测试是否能随机相同数字)
-超类已经覆盖了equals,从超类继承过来的行为对于子类也是合适的(Set List Map)
-类是私有的或包级私有的,可以确定它的equals方法永远不会被调用
2.equals的通用约定
-自反性(reflexive):对于任何非null的引用值X,x.equals(x)必须返回true
-对称性(symmetric):对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true
-传递性(transitive):对于任何非null的引用值x和y和z,如果x.equals(y)返回true,那么y.equals(z)也返回true,z.equals(x)必须为true
-一致性(consistent):对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会调用x.equals(y)就会一致地返回true,或者一致地返回false
-非空性(Nonnuooity):对于任何非null的引用值X,x.equals(null)必须返回false
3.实现高质量equals方法诀窍
-使用==操作符检查”参数是否为这个对象的引用”
-使用instanceof操作符检查”参数是否为正确类型”
–正确类型:指equals方法所在的类或者接口(Set List Map Map.Entry) 如果类实现的接口改进了equals约定,允许在实现了该接口的类之间进行比较,那么就使用该接口
-把参数转换成正确的类型(转换之前会进行instanceof测试确保成功)
-对于该类中的每个”关键(significant)”域,检查参数中的域是否与该对象中对应的域相匹配
-当编写完成了equals方法后,它是否是对称的,传递的,一致的
-覆盖equals时总要覆盖hashCode
-不要让equals方法过于智能
-不要将equals生命中的Object对象替换为其他类型
public boolean equals(Object o) {
// 违反equals的对称性
// if(o instanceof CaseInsensitiveString)
// return s.equalsIgnoreCase(((CaseInsensitiveString) o).s);
// if(o instanceof String)
// return s.equalsIgnoreCase((String)o);
// return false;
// 解决方案 – CaseInsensitiveString区分字符串大小写
return o instanceof CaseInsensitiveString &&
((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}

//比较普通点和有色点,以及相反的情形时,可能会得到不同的结果
@Override public boolean equals(Object o){
    if(!(o instanceof ColorPoint))
        return false;
    //cp.equals()进行比较时忽略颜色信息
    //提供对称性  牺牲传递性
    //无法在扩展可实例化类的同时,既增加新的值组件,同时又保留equals约定
    if(!(o instanceof ColorPoint))
        return o.equals(this);
    return super.equals(o) && ((ColorPoint)o).color == color;
}

//用getClass测试代替instanceof
@Override public boolean equals(Object o){
    if(o == null || o.getClass()!=getClass())
        return false;
    PointString ps =(PointString)o;
    return ps.x == x && ps.y == y;
}
posted on   qwop  阅读(158)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示