这一章主要讲解Object类中的方法, Object类是所有类的父类,所以它的方法也称得上是所有对象都通用的方法

第八条 覆盖equals时需要遵守的约定

Object中的equals实现,就是直接对对象进行相等的比较:

    public boolean equals(Object obj) {
return (this == obj);
}

那么什么时候需要覆盖equals呢?

当你的类有自己的逻辑相等,而不是对象相等时,应该自己实现equals,比如Date和Interger,他们的相等比较不仅是对象相等,需要涉及到内部值的相等,

// Integer的equals实现:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
// Date的equals实现:
public boolean equals(Object obj) {
return obj instanceof Date && getTime() == ((Date) obj).getTime();
}

equals方法的实现必须满足等价关系(温习一下数学基本概念):

1.自反性。对于任何非null的引用值x,x.equals(x) 必须为true

2.对称性。对于非null的x和y,x.equals(y)推导出y.equals(x)

3.传递性。非null的xyz,x.equals(y) 并且y.equals(z),那么x.equals(z)

这里讨论了一个典型例子。自类扩展了父类,增加了新的值组件(变量),那么equals很难在父类子类之间同时生效,比如父类的equals就缺少子类的新增变量的比较,子类的equals来比较父类,父类缺少子类新增的变量。

文中提出了一种方法,基于组合优先于继承的原则,将子类独立出来,增加自己的值组件,并在子类中实现父类的实例,这样可以同时用equals比较这两部分

4.一致性。任何非null的xy,只要equals的比较操作在对象中所用的信息没有改变,多少次操作得到的值应该一样

5.非空性。一般并不需要在equals里显示的检查null == obj,因为 if (obj instanceof Integer) {}已经做了这个工作

关于写equals的几个建议:

1.优先使用==检查是否为这个对象的引用

2.使用instanceof检查参数是否为正确类型

3.equals覆盖时总要覆盖hashcode(),见第九条

4.不要让equals太智能太复杂

5.不要讲equals的参数改为其他类型,应该为Object

第九条 覆盖equals时总要覆盖hashCode

集合的操作都是基于散列的,比如从hashmap get 元素,先通过hashcode获取散列码,通过散列码找到对应的散列桶((hash bucket),然后在散列桶中通过equals找打对应的对象

所以,如果对象有同样的equals值,他们的hashcode应该也是相等的(Object规范 JAVA SE6);

反过来,有同样的hashCode,他们的eqauls值不一定要相同!

在计算散列码的过程中,如果equals中没有用到的域(比如成员变量),hashCode中也最好不要!

书中讲了一些简单的方法来获取hashCode,对于Integer,就是返回int value,boolean返回1或者0,我们看一下String的源码:

    public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

String类会将string转换为value这样一个数(private final char value[])
所以就是对数组的每一个元素进行处理,最后获取到散列值组合

[Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第八 ---- 九条的更多相关文章

  1. Effective Java读书笔记——第三章 对于全部对象都通用的方法

    第8条:覆盖equals时请遵守通用的约定 设计Object类的目的就是用来覆盖的,它全部的非final方法都是用来被覆盖的(equals.hashcode.clone.finalize)都有通用约定 ...

  2. [Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第十---十一条

    第十条 始终覆盖toString() toString的实现可以使类使用起来更加舒适,在执行println等方法时打印出定制信息. 一单实现了自己的toString,指定输出的固定格式,在方法的文档说 ...

  3. [Java读书笔记] Effective Java(Third Edition) 第 3 章 对于所有对象都通用的方法

    第 10 条:覆盖equals时请遵守通用约定 在不覆盖equals方法下,类的每个实例都只与它自身相等. 类的每个实例本质上都是唯一的. 类不需要提供一个”逻辑相等(logical equality ...

  4. [Effective Java]第三章 对所有对象都通用的方法

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  5. [Effective Java 读书笔记] 第三章类和接口 第二十三-- ??条

    第二十三条 请不要再新代码中使用原生态类型 1 使用原生态类型,就失去了泛型在安全性和表述性方面的所有优势,所以新代码中不要使用原生态类型 2 List<String>可以传递给List作 ...

  6. [Effective Java 读书笔记] 第三章类和接口 第二十-二十一条

    第二十条 用函数对象表示策略 函数指针(JAVA的函数指针,是指使用对象的引用来作为参数,传递给另一个对象的方法)主要用来实现策略模式,为了在JAVA中实现这种模式,要申明一个接口来表示该策略,并为每 ...

  7. [Effective Java 读书笔记] 第三章类和接口 第十三 -- 十四条

    第十三条 使类和成员的可访问性最小化 总得来说,我们应该尽量将成员的访问范围限制到最小!有利于解耦,开发.测试和优化都能够更加独立. 对于成员(域,方法,嵌套类和嵌套接口),有四种可能的访问级别,访问 ...

  8. [Effective Java 读书笔记] 第三章类和接口 第十八--十九条

    十八条 接口优于抽象类 接口的特点: 1.一个类可以实现多个接口,不能继承多个类(抽象类) 2.接口不能有具体的方法实现,只定义标准类型 骨架类: 即实现一个abstract类来实现接口,提供给其他类 ...

  9. [Effective Java 读书笔记] 第三章类和接口 第十六条

    第十六条 复合优先于继承 如果不确定B和A的关系是,is-a的关系,B确实也是A,那么久不应该使用B继承A,否则会暴露实现细节, 你的实现都会限制在原始的实现上. 书中举的第一个例子,实现了一个类ex ...

随机推荐

  1. Numpy常用方法及应用总汇

    目录 Numpy 1.基本操作 1.1数组转换 1.2数组生成 1.3文件读取 1.4查看操作 2.数据类型 2.1指定数据类型: 2.2查看数据类型 2.3数据类型转换 3.数组运算 3.1数组间运 ...

  2. Java 从入门到进阶之路(二十二)

    在之前的文章我们介绍了一下 Java 中的  集合框架中的Collection 中的一些常用方法,本章我们来看一下 Java 集合框架中的Collection 的迭代器 Iterator. 当我们创建 ...

  3. 如何用visual studio code更好的编写python

    目录 1.先决条件 2.Visual Studio Code扩展安装Python 3.Visual Studio Code扩展安装Python for VSCode 4.Visual Studio C ...

  4. Spring学习记录6——ThreadLocal简介

    Spring通过各种模板类降低了开发者使用各种数据持久化技术的难度.这些模板类是线程安全的,所以 多个DAO可以复用同一个模板实例而不会发生冲突.在使用模板类访问底层数据时,模板类需要绑定数据连接或者 ...

  5. <s:select>自动加标签

    在使用<s:select>标签时,发现页面位置不对,查看页面源码发现 <tr> <td class="tdLabel"></td> ...

  6. git工作中总结2

    目的:在远程分支上添加新文件(代码) 1.clone分支 git clone -b 分支 url cd到文件夹,添加文件到改目录下 2.创建新的分支并切换 git checkout -b dev(本地 ...

  7. 5.JavaSE之数据类型详解

    数据类型: 强类型语言: 要求变量的使用严格要求符合规定,写错了就不行,所有变量都必须先定义后才能使用,否则是不能使用的. 比如Java.C++都是强类型语言,也就是说,一旦定义了一个变量,只定义了某 ...

  8. HGE引擎改进——2014/3/4

    2014/3/4 更新 1.提升资源包管理效率 2.Show库整合.目前Show库有Picture.Frame.Animation和Particle类,以及PictureData和ParticleSy ...

  9. atx测试框架实现手机应用UI自动化测试

    最近工作中遇到游戏APP需要实现UI自动化测试,这个app中真的是典型的混合App,有Android原生控件,有webview控件,以及游戏操作页面.研究了Appium,发现appium实现跨应用操作 ...

  10. 网络流(最大流-Dinic算法)

    摘自https://www.cnblogs.com/SYCstudio/p/7260613.html 网络流定义 在图论中,网络流(Network flow)是指在一个每条边都有容量(Capacity ...