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 ...
随机推荐
- Pipeline组Beta版本发布说明
项目名称 Pipeline 项目版本 Beta版本 负责人 北京航空航天大学计算机学院 IloveSE 小组 联系方式 http://www.cnblogs.com/IloveSE 要求发布日期 20 ...
- caffe2安装教程
相比于网上的安装教程不如直接看官方安装教程:https://caffe2.ai/docs/getting-started.html?platform=windows&configuration ...
- 【week2】 构建之法 读后感及问题
上一次读后感涵盖前五章的内容包括个人技术,结对合作,小组项目等.本周作业的燃尽图以及站立会议是关于<构建之法>第六章的内容,所以关于这一章的读后感涵盖在上两篇博客中. 第七章 MSF 介绍 ...
- [CLR via C#]基元类型
一.什么是基元类型 某些数据类型如此常用,以至于许多编译器允许代码以简化的语法来操纵它们.例如,可以使用以下语法来分配一个整数: System.Int32 a = new System.Int32() ...
- AngularJS 中特性(attr)和属性(prop)的区别
attr() 和 removeAttr() 方法是对特性进行处理的, 而 prop() 是对属性进行操作的 , 但是很多时候操作的东西是同一个 , 但是也是有区别的, 区别在于prop方法处理的是被 ...
- WASM
WASM WebAssembly https://webassembly.org/ https://github.com/appcypher/awesome-wasm-langs https://me ...
- 【Python】面向对象--类的特殊成员方法
类的特殊成员方法 1. __doc__ 表示类的描述信息 class Func(object): '''__doc__方法是用来打印类的描述信息''' def tell(self): pass def ...
- Luogu2540 斗地主增强版(搜索+动态规划)
单纯的暴搜似乎还是很好写的,然而过不了.出完顺子之后答案是可以dp出来的,于是大力搜然后大力dp就好了. dp时强行讨论完了几乎所有拆牌情况,理性愉悦一发. #include<iostream& ...
- Luogu3147 USACO16OPEN 262144(动态规划)
感觉上这个题是可以直接暴力的,每次根据一段连续最小值个数的奇偶性决定是否划分区间,递归处理.然而写起来实在太麻烦了. 设f[i][j]为以i为左端点合并出j时的右端点.则有f[i][j]=f[f[i] ...
- web服务器压测工具siege、ab
web服务器压测工具也挺多,这里只介绍我用过的这两种--siege(for linux).ab(for windows). 一.siege 1.简介: Siege是一款开源的压力测试工具,设计用于评估 ...