[Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第八 ---- 九条
这一章主要讲解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 读书笔记] 第三章 对所有对象都通用的方法 第八 ---- 九条的更多相关文章
- Effective Java读书笔记——第三章 对于全部对象都通用的方法
第8条:覆盖equals时请遵守通用的约定 设计Object类的目的就是用来覆盖的,它全部的非final方法都是用来被覆盖的(equals.hashcode.clone.finalize)都有通用约定 ...
- [Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第十---十一条
第十条 始终覆盖toString() toString的实现可以使类使用起来更加舒适,在执行println等方法时打印出定制信息. 一单实现了自己的toString,指定输出的固定格式,在方法的文档说 ...
- [Java读书笔记] Effective Java(Third Edition) 第 3 章 对于所有对象都通用的方法
第 10 条:覆盖equals时请遵守通用约定 在不覆盖equals方法下,类的每个实例都只与它自身相等. 类的每个实例本质上都是唯一的. 类不需要提供一个”逻辑相等(logical equality ...
- [Effective Java]第三章 对所有对象都通用的方法
声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...
- [Effective Java 读书笔记] 第三章类和接口 第二十三-- ??条
第二十三条 请不要再新代码中使用原生态类型 1 使用原生态类型,就失去了泛型在安全性和表述性方面的所有优势,所以新代码中不要使用原生态类型 2 List<String>可以传递给List作 ...
- [Effective Java 读书笔记] 第三章类和接口 第二十-二十一条
第二十条 用函数对象表示策略 函数指针(JAVA的函数指针,是指使用对象的引用来作为参数,传递给另一个对象的方法)主要用来实现策略模式,为了在JAVA中实现这种模式,要申明一个接口来表示该策略,并为每 ...
- [Effective Java 读书笔记] 第三章类和接口 第十三 -- 十四条
第十三条 使类和成员的可访问性最小化 总得来说,我们应该尽量将成员的访问范围限制到最小!有利于解耦,开发.测试和优化都能够更加独立. 对于成员(域,方法,嵌套类和嵌套接口),有四种可能的访问级别,访问 ...
- [Effective Java 读书笔记] 第三章类和接口 第十八--十九条
十八条 接口优于抽象类 接口的特点: 1.一个类可以实现多个接口,不能继承多个类(抽象类) 2.接口不能有具体的方法实现,只定义标准类型 骨架类: 即实现一个abstract类来实现接口,提供给其他类 ...
- [Effective Java 读书笔记] 第三章类和接口 第十六条
第十六条 复合优先于继承 如果不确定B和A的关系是,is-a的关系,B确实也是A,那么久不应该使用B继承A,否则会暴露实现细节, 你的实现都会限制在原始的实现上. 书中举的第一个例子,实现了一个类ex ...
随机推荐
- 算法笔记codeup-Contest100000568
A #include <stdio.h> int main() { ; ; while(a) { sum=sum+a; a--; } printf("%d",sum); ...
- 【STACK】Several待填的坑
待学的习: https://www.cnblogs.com/xiao-ju-ruo-xjr/p/9149792.html 待写的题: loj#3184:「CEOI2018」斐波那契表示法 luoguP ...
- 关于SOA架构设计的案例分析
关于SOA架构设计的案例分析 面向服务的体系结构(SOA)是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来.它可以根据需求通过网络对松散耦合的粗粒度应 ...
- itext5和itext7操作pdf平铺和图层叠加(tiling, and N-upping)
区别 itext5 生成pdf版本:1.4(Acrobat5.x) itext7 生成pdf版本:1.7(Acrobat8.x) iText7生成的pdf文件大, itext7 Java库更加系统和完 ...
- c/python 的区别
c python ...
- 线段树+Lazy标记(我的模版)
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ...
- 最短路径-Dijkstra+Floyd+Spfa
Dijkstra算法: Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra ...
- Git基础常用功能
一.安装 具体查看 安装Git 二.使用 基础知识 工作区(Workspace):就是你在电脑里能看到的项目目录. 暂存区(Index / Stage):临时存放更改的地方,使用命令"git ...
- Linux下启动/关闭Oracle
一.Linux下启动Oracle Linux下启动Oracle分为两步: 1)启动监听: 2)启动数据库实例: 1.登录服务器,切换到oracle用户,或者以oracle用户登录 [admin@dat ...
- 在Linux环境下设置 ora-01031:insufficient privileges解决方法总结
今天需要使用sys用户处理问题,但是报错上面ora-01031:insufficient privileges. 在网上有很多方法,这个是自己经过测试的方法步骤. 1:首先检查文件sqlnet.ora ...