Java基础:Object类中的equals与hashCode方法
前言
这个系列的文章主要用来记录我在学习和复习Java基础知识的过程中遇到的一些有趣好玩的知识点,希望大家也喜欢。
一切皆对象
对于软件工程来说面向对象编程有一套完整的解决方案:OOA、OOD、OOP, 作为程序员来讲,OOP其实是直接接触最多的。Java中OOP最直接的体现就是java.lang.Object了,一切都是对象(除了原生类型,原生类型的 PrimitiveClass对象由JVM启动时生成和加载),Object类主要就只有这么几个方法,其中getClass是反射的基石,notify、notifyAll、wait是多线程并发时常用的方法,其中比较有意思的就是hashCode与equals了,也是面试的时候面试官很喜欢问的一个问题。
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
// finnal的本地方法,子类不能重写
public final native Class<?> getClass();
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
// 本地方法wait的包装方法
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
// 为什么hashCode是本地方法,而equals却是成员方法呢?
public native int hashCode();
public boolean equals(java.lang.Object obj) {
return (this == obj);
}
protected native java.lang.Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
// 对象成员方法,对象被回收时执行的方法,一般不用来释放资源,因为GC的时机对程序员来说是不可控的
protected void finalize() throws Throwable { }
}
equals与hashCode
面试题的标准答案是:如果两个对象a和b满足a.equals(b) == true,则它们的散列码(hash code)应当要相同,反之则不一定。这里也就引申出:重写了类的equals方法之后一定要重写hashCode方法,这种情况最常见的是在entity bean中,当bean跟容器类搭配使用时如果重写了equals而没重写hashCode就会引起问题,这里先来看看HashMap的getEntry方法,循环中就是先判断两个对象的hash值(由对象的hashCode计算得到)是否相等,再判断两个对象是否为同一对象最后才调equals方法来判断,这样可以减少equals方法的调用次数,提升容器的性能,如果大家看看Java容器类的源码就会发现大神们对hash思想的运用简直炉火纯青(生活中哈希的应用也随处可见:年月日、时分秒就是对时间流的哈希散列)
final Entry<K,V> getEntry(Object key) {
int hash = (key == null) ? 0 : hash(key);
for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) {
Object k;
if (e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k))))
return e;
}
return null;
}
下面是一张抽象化的对比图:

hashCode一般是一个int值,比较两个对象的hashCode就是比较两个int值,Java中对原生类型操作的性能肯定要好于对方法的调用,所以我们才会在Java容器中看到那么多对hash的应用。
上面这张图也可以直观看出为什么说两个对象equals为true的话hashCode就一定相同,反之则不一定。
equals方法的四大特性
通过equals方法的注解就能清晰看到Java大神们给我们总结的4大特性了(如果在面试中遇到equasl和hashCode的问题时一遍把四大特性阐述一下会是个小小的加分项):
1、自反性:自己跟自己比较返回true
2、对称性:x.equals(y) == y.equals(x)
3、传递性:x.equals(y) == true 且 y.equals(z) == true 则 x.equals(z) == true
4、一致性:多次调用equals返回结果相同
(null与任何对象比较都应该返回false)

Java基础:Object类中的equals与hashCode方法的更多相关文章
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- java集合(3)- Java中的equals和hashCode方法详解
参考:http://blog.csdn.net/jiangwei0910410003/article/details/22739953 Java中的equals方法和hashCode方法是Object ...
- Java中的equals和hashCode方法详解
Java中的equals和hashCode方法详解 转自 https://www.cnblogs.com/crazylqy/category/655181.html 参考:http://blog.c ...
- 转:Java中的equals和hashCode方法详解
转自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这 ...
- Java Object类中的equals方法
Object类中的equals方法用于检测一个对象是否等于另外一个对象.在Object类中,这个方法将判断两个对象是否具有相同的引用.如果两个对象具有相同的引用,它们一定是相等的.从这点上看,将其作为 ...
- Object 类中的 equals方法
1 相等与同一 如果两个对象具有相同的类型以及相同的属性值,则称这两个对象相等.如果两个引用对象指的是同一个对像,则称这两个变量同一.Object类中定义的equals 函数原型为:public bo ...
- 重写Object类中的equals方法
Object是所有类的父亲,这个类有很多方法,我们都可以直接调用,但有些方法并不适合,例如下面的student类 public class Student { //姓名.学号.年纪 private S ...
- 一、基础篇--1.1Java基础-Object类中常见的方法,为什么wait notify会放在Object里边
这是个设计相关的问题,它考察的是面试者对现有系统和一些普遍存在但看起来不合理的事物的看法.回答这些问题的时候,你要说明为什么把这些方法放在Object类里是有意义的,还有不把它放在Thread类里的原 ...
- Java基础——Object类
一.概述: Object是类层次结构的根,每个类都可以将Object作为超类.所有类都直接或者间接的继承该类 有一个构造方法 public Object() 面向对象中子类的构造方法默认访问的是父类的 ...
随机推荐
- 树莓派3B+上运行.Net Core项目
最近买了个树莓派3B+,准备把自己写的一个.Net Core爬虫挂在上面跑 买之前没有想到树莓派因为是今年新出的,导致驱动以及系统啥的都不是很完善,导致走了很多弯路,早知道买树莓派3就不用那么多折腾了 ...
- ubuntu解压时中文出现乱码
一.乱码类似这样的:╫╩┴╧╖┤╤▌▓т╒╛╦┘╢╚│ 今天遇到需要上传十几G的图片,在wins上压缩成zip格式,在上传到服务器上,结果出现乱码.然后各种百度心塞. 最初查到原因: 这个主要是因为z ...
- 用C#+Selenium+ChromeDriver 生成我的咕咚跑步路线地图
先上结果: 之前 在公司业务中用过java+Selenium+ChromeDriver ,使用起来非常顺手,可以完美模拟真实的用户浏览行为.最近休息的时候想用C#也试一下,于是有了本文. 实现原理一样 ...
- EF Oracle:错误 175
错误 1 错误 175: 具有固定名称“Oracle.DataAccess.Client”的 ADO.NET 提供程序未在计算机或应用程序配置文件中注册或无法加载.有关详细信息,请参阅内部异常. 安装 ...
- Java中的队列同步器AQS
一.AQS概念 1.队列同步器是用来构建锁或者其他同步组件的基础框架,使用一个int型变量代表同步状态,通过内置的队列来完成线程的排队工作. 2.下面是JDK8文档中对于AQS的部分介绍 public ...
- 吴恩达机器学习笔记53-高斯分布的算法(Algorithm of Gaussian Distribution)
如何应用高斯分布开发异常检测算法呢? 异常检测算法: 对于给定的数据集
- [Swift]LeetCode130. 被围绕的区域 | Surrounded Regions
Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'. A reg ...
- python之PIL库(Image模块)
PIL(Python Image Library)是python的第三方图像处理库,PIL的功能非常的强大,几乎被认定是Python的官方图像处理库了. 由于PIL仅支持到python2.7于是一群志 ...
- 专访 | 新浪架构师:0-5年Java工程师的职业规划如何做?
经历了2018年末的阵痛,大家都积攒着一股暗劲蠢蠢欲动. 3月初即将迎来2019年互联网行业换工作的大潮,技术工程师的升级换位对于一家互联网公司来说无疑是命脉般的存在——技术强则公司强! 如何做一个抢 ...
- Python内置函数(29)——help
英文文档: help([object]) Invoke the built-in help system. (This function is intended for interactive use ...