Item 8 覆盖equals时请遵守通用约定
在覆盖equals方法的时候,你必须要遵守它的通用约定,不遵守,写出来的方法,会出现逻辑错误。下面是约定的内容:
- 自反性。对于任何非null的引用值,x.equals(x)必须返回true。
- 对称性。对于任何非null的引用值x和y,当且仅当y.equals(x)返回true时,x.equals(y)必须返回true。
- 传递性。对于任何非null的引用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)也必须返回true。
- 一致性。对于任何非null的引用值x和y,只要equals的比较操作在对象中所用的信息没有被修改,多次调用x.equals(y)就会一致地返回true,或者一致地返回false。
- 对于任何非null的引用值x,x.equals(null)必须返回false。
对称性
public final class CaseInsensitiveString {
private final String s ; public CaseInsensitiveString(String s) {
if (s == null)
throw new NullPointerException();
this. s = s;
} // Broken - violates symmetry!
@Override
public boolean equals(Object o) {
if (o instanceof CaseInsensitiveString)
return s.equalsIgnoreCase(((CaseInsensitiveString) o). s);
if (o instanceof String) // One-way interoperability!
return s.equalsIgnoreCase((String) o);
return false;
} // This version is correct.
// @Override public boolean equals(Object o) {
// return o instanceof CaseInsensitiveString &&
// ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
// } public static void main(String[] args) {
CaseInsensitiveString cis = new CaseInsensitiveString("Polish" );
String s = "polish";
System.out.println(cis.equals(s) + " " + s.equals(cis));
}
}
public class ColorPoint extends Point {
private final Color color ; public ColorPoint( int x, int y, Color color) {
super(x, y);
this.color = color;
} // Broken - violates symmetry!
@Override
public boolean equals(Object o) {
if (!(o instanceof ColorPoint))
return false ;
return super .equals(o) && ((ColorPoint) o).color == color;
} // Broken - violates transitivity!
// @Override public boolean equals(Object o) {
// if (!(o instanceof Point))
// return false;
//
// // If o is a normal Point, do a color-blind comparison
// if (!(o instanceof ColorPoint))
// return o.equals(this);
//
// // o is a ColorPoint; do a full comparison
// return super.equals(o) && ((ColorPoint)o).color == color;
// } public static void main(String[] args) {
// First equals function violates symmetry
Point p = new Point(1, 2);
ColorPoint cp = new ColorPoint(1, 2, Color.RED);
System. out.println(p.equals(cp) + " " + cp.equals(p)); // Second equals function violates transitivity
ColorPoint p1 = new ColorPoint(1, 2, Color.RED);
Point p2 = new Point(1, 2);
ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
System. out.printf("%s %s %s%n" , p1.equals(p2), p2.equals(p3),
p1.equals(p3));
}
}
public class Point {
private final int x;
private final int y; public Point(int x, int y) {
this.x = x;
this.y = y;
} @Override
public boolean equals(Object o) {
if (!(o instanceof Point))
return false ;
Point p = (Point) o;
return p.x == x && p.y == y;
} // See Item 9
@Override
public int hashCode() {
return 31 * x + y ;
}
} public enum Color {
RED, ORANGE , YELLOW, GREEN, BLUE, INDIGO , VIOLET
} public class ColorPoint {
private final Point point ;
private final Color color ; public ColorPoint(int x, int y, Color color) {
if (color == null)
throw new NullPointerException();
point = new Point(x, y);
this.color = color ;
} /**
* Returns the point -view of this color point.
*/
public Point asPoint() {
return point ;
} @Override
public boolean equals(Object o) {
if (!(o instanceof ColorPoint))
return false ;
ColorPoint cp = (ColorPoint) o;
return cp.point .equals(point ) && cp.color.equals( color);
} @Override
public int hashCode() {
return point .hashCode() * 33 + color.hashCode();
}
}
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof InetAddress)) {
- return false;
- }
- return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress);
- }
*
@Override
* public boolean equals(Object obj) {
* if (!(obj instanceof InetAddress)) {
* return false;
* }
* return Arrays.equals(this.ipaddress, ((InetAddress) obj).ipaddress);
* }
Item 8 覆盖equals时请遵守通用约定的更多相关文章
- 第8条:覆盖equals时请遵守通用约定
第8条:覆盖equals时请遵守通用约定 引言:尽管Object是一个具体类,但是设计它主要是为了拓展.它所有的非final方法(equals.hashCode.toString.clone和fina ...
- 第八条:覆盖equals时请遵守通用约定
==是物理相等 equals是逻辑相等 因为每个类的实例对象本质上都是唯一的 ,利用物理相等(==)是指一个实例只能相等于它自己. 利用逻辑相等是(equals)指 一个实例是否和另一个实例的某些关键 ...
- 覆盖equals时请遵守通用约定
Object类中非final修饰的方法有equals().hashCode().toString().finalize().clone()1.equals()方法不需要被覆盖的情况:1)实例化的对象只 ...
- 【Effective Java】4、覆盖equals时请遵守通用约定
package cn.xf.cp.ch02.item8.transitivity; public class Point { private final int x; private final in ...
- 第10项:重写equals时请遵守通用约定
重写equals方法看起来似乎很简单,但是有许多重写方式会导致错误,而且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每个实例都只能与它自身相等.如果满足了以 ...
- 覆盖equals方法时请遵守通用约定
覆盖equals方法时请遵守通用约定 覆盖equals方法看起来很简单,但是有许多覆盖方式会导致错误,并且后果很严重.最容易避免这种类问题的方法就是不覆盖equals方法,在这种情况下,类的每个实 ...
- EffectiveJava(8)覆盖equals是要遵守的约定
覆盖equals是要遵守的约定 1.覆盖种类: -类的每个1实例本质上都是唯一的 -不关心类是否提供了"逻辑相等"的测试功能(Random测试是否能随机相同数字) -超类已经覆盖了 ...
- Item 9 覆盖equals时总要覆盖hashCode
为什么覆盖equals时,总要覆盖hashCode? 原因是,根据Object规范: 如果两个对象根据equals(Object)方法比较是相等的,那么调用这两个对象中任意一个对象的hashCod ...
- 重写equals时,遵守的规定
0 正确的equals方法 public class MyClass { // 主要属性1 private int primaryAttr1; // 主要属性2 private int prima ...
随机推荐
- 20145214 《Java程序设计》第4周学习总结
20145214 <Java程序设计>第4周学习总结 教材学习内容总结 继承 继承基本上就是避免多个类间重复定义共同行为.要避免在程序设计上出现重复,可以把相同的程序代码提升为父类. 关键 ...
- ubuntu上的inpack测试
测试linpack 配置 配置linpack环境是整个过程中最麻烦的,也可能是因为我在配置的过程中出现了很多小问题吧.大概有3天的时间除了上课就在配置环境. 问题 总结起来问题和解决方法有这些 1.路 ...
- (beta冲刺5/7)
团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 推进后端完成安卓端接口的开发 在测试中发现返回地图接口存在错误(待修复) 推进 ...
- 项目uml
[团队信息] 团队项目: 小葵日记--主打记录与分享模式的日记app 队名:日不落战队 队员信息及贡献分比例: 短学号 名 本次作业博客链接 此次作业任务 贡献分配 备注 501 安琪 http:// ...
- k邻近算法理解及代码实现
github:代码实现 本文算法均使用python3实现 1 KNN KNN(k-nearest neighbor, k近邻法),故名思议,是根据最近的 $ k $ 个邻居来判断未知点属于哪个类别 ...
- 自定义类属性设置及setter、getter方法的内部实现
属性是可以说是面向对象语言中封装的一个体现,在自定义类中设置属性就相当于定义了一个私有变量.设置器(setter方法)以及访问器(getter方法),其中无论是变量的定义,方法的声明和实现都是系统自动 ...
- js设计模式之代理模式以及订阅发布模式
为啥将两种模式放在一起呢?因为这样文章比较长啊. 写博客的目的我觉得首要目的是整理自己的知识点,进而优化个人所得知识体系.知识成为个人的知识,就在于能够用自己的话表达同一种意义. 本文是设计模式系列文 ...
- C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- 网页中NPIO对Excel的操作实例
上一节是在wpf中实现对excel的操作方法,这一节看看网页中如何封装实现对excel的上传导入和下载保存的. 看看效果图:
- select、poll、epoll模型对比
select.poll.epoll模型对比 先说Select: 1.Socket数量限制:该模式可操作的Socket数由FD_SETSIZE决定,内核默认32*32=1024. ...