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 ...
随机推荐
- C++基础和STL,Effective C++笔记
这个作者总结的c++基础,特别好. 可以看看. http://blog.csdn.net/tham_/article/details/51169792
- java 基础--继承--007
1,子类只能继承父类所有非私有成员 2,子类不能继承父类的构造方法,但可以通过super去访问父类构造方法 3,子类成员变量和父类成员变量名称不一样,如果一样类似于重写,按子类处理,如果一样,就近原则 ...
- python2 对URL编码进行编译
在请求页面时有时会返回类似: %E8%AF%A5985%E5%A4%A7%E5%AD%A6%E5%B8%B8%E5%B9%B4%E4%BD%8D%E5%B1%85%E5%9B%BD%E5%86%85% ...
- Oracle导数据到SQL server的方法总结
通过oracle10g 访问sql server 2008 导数据步骤 最近在项目中遇到要将Oracle数据库的数据导入到SQL server数据库中,解决办法如下: 一.准备工作 配置Oracle ...
- Dom选择器以及内容文本操作
1. DOM:文档对象模型.把整个HTML当做大的对象.每一个标签认为是一个对象.(每一个个体就是一个对象) 2. 查找: 直接查找 var obj=document.getElementById(& ...
- python 深浅copy的例子
1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象.2. copy.deepcopy 深拷贝 拷贝对象及其子对象一个很好的例子:import copya = [1, 2, 3, ...
- [luogu3806]【模板】点分治1
description 求树上长度为\(k\)的路径是否存在. data range \[n\le 10000,k\le 10000000\] solution 点分治复习... 使用普通的点分治枚举 ...
- [SOJ #47]集合并卷积
题目大意:给你两个多项式$A,B$,求多项式$C$使得:$$C_n=\sum\limits_{x|y=n}A_xB_y$$题解:$FWT$,他可以解决形如$C_n=\sum\limits_{x\opl ...
- Codeforces Round #469 (Div. 2) F. Curfew
贪心 题目大意,有2个宿管分别从1和n开始检查房间,记录人数不为n的房间个数,然后锁住房间. 没有被锁的房间中的学生可以选择藏在床底,留在原地,或者转移(最远转移d个房间) 然后抄了网上大神的代码 ...
- CF724E Goods transportation 最小割 DP
照惯例CF的题不放原题链接... 题意:一个序列上有n个点,每个点有权值pi和si.表示这个点一开始有pi个物品,最多可以卖出si个物品,每个点都可以把物品向编号更大的点运输,但是对于i < j ...