面试必问hashCode和equals

面试必问hashCode和equals

面试必问hashCode与equals

hashCode和equals用来标识对象,两个方法协同工作可用来判断两个对象是否相等。这两方法来源于:java.lang.Object

www.zeeklog.com  - 面试必问hashCode和equals

众所周知,根据生产的哈希将数据散列开来,可以是存取元素更快,对象通过调用Object.hashCode();生成哈希值;由于不可避免地存在哈希值冲突的情况,因此,当hashCode相同时,还需要进行equals方法比较,但是,若hashCode不同,将直接判定两个对象不相等,跳过equals,这加快了冲突处理效率。

Object类定义中对hashCode和equals要求如下:

在Map和Set类集合中,用到这两个方法时,首先判断hashCode的值,如果hash值相等,则在判断equals的结果,HashMap中get方法判断如下:

先进性hash值比较,然后进行equals比较。如果hash只不相等则equals方法都不用比较了。

这样一来就是要求hashCode方法要求就高了很多,一个优秀的哈希算法应尽可能地让元素均匀分布,降低冲突概念,即就是尽量在equals不相等的情况下hash值也不相等,这样使用&&或者||短路操作一旦生效,会极大地提高程序的执行效率。如果自定义Map的键,那么必须重写equals和hashCode方法。

此外,因为Set存储的是不重复的对象,依据hashCode和equals进行判断,所以Set存储的自定义对象也必须重写这两个方法。此时,如果重写equals而不重写hashCode,到底会有什么影响呢?

请看下面的代码:

输出结果:3

看源码发现Object中的hashCode方法是native方法:

那就只能去看虚拟机中的源码了,源码下载地址:

openJDK 7下载地址1:http://download.java.net/openjdk/jdk7

网上找找比什么盘,CSDN上都可以找到,并且下载的快,自己看着办咯。

进入openjdk\jdk\src\share\classes\java\lang目录下,可以看到 Object.java源码,打开

打开openjdk\jdk\src\share\native\java\lang\目录,查看Object.c文件,可以看到hashCode()的方法被注册成有JVM_IHashCode方法指针来处理:

JVM_IHashCode方法指针在 openjdk\hotspot\src\share\vm\prims\jvm.cpp中定义,如下:

如上可以看出,JVM_IHashCode方法中调用了ObjectSynchronizer::FastHashCode方法

ObjectSynchronizer::fashHashCode()方法在 openjdk\hotspot\src\share\vm\runtime\synchronizer.cpp文件中实现。

以上这么多代码的核心部分:

这里也就印证了:hashCode就是根据对象的地址进行相关计算得到int类型数值的。

上面EqualsDemo没有写hashCode,所以导致最后的结果是3,如果不想存储重复的元素,那么需要在EqualsDemo类中重写hashCode方法,代码如下:

最后运行Test类,得出的结果:1

因为上面的name是String类型,并且String类重写了hashCode方法了,所以这里就直接使用了。

equals的实现方式与类的具体业务逻辑有关,但又各不相同,因而应尽量分享源码来确定其判断结果,比如下面的代码:

输出:equal

两个不同的集合,结果输出相等。让我们来看看这两个集合的equals方法是怎么实现的:

看其源码发现两个集合都是使用AbstractList中的equals方法(JDK版本是1.8),每个版本可能有差别。

面试题

两个对象的equals为true,则两个对象的hashCode相等。

两个对象的hashCode相等,两个对象的equals不一定为true。

Read more

超快速,使用ChatGPT编写回归和分类算法

超快速,使用ChatGPT编写回归和分类算法

本文将使用一些 ChatGPT 提示,这些提示对于数据科学家在工作时非常重要。 微信搜索关注《Python学研大本营》,加入读者群,分享更多精彩 以下是一些示例ChatGPT 提示的列表以及数据科学家的响应。 ChatGPT 提示 为决策树回归算法生成 python 代码。 下面是使用scikit-learn在 Python 中进行决策树回归的示例代码: import numpy as np import matplotlib.pyplot as plt from sklearn.tree import DecisionTreeRegressor # Generate random data rng = np.random.default_rng() x = 5 * rng.random(100) y = np.sin(x) + 0.

By Ne0inhk
力扣每日一题:993.二叉树的堂兄弟节点 深度优先算法

力扣每日一题:993.二叉树的堂兄弟节点 深度优先算法

993.二叉树的堂兄弟节点 难度:简单 题目: 在二叉树中,根节点位于深度 0 处,每个深度为 k 的节点的子节点位于深度 k+1 处。 如果二叉树的两个节点深度相同,但 父节点不同 ,则它们是一对堂兄弟节点。 我们给出了具有唯一值的二叉树的根节点 root ,以及树中两个不同节点的值 x 和 y 。 只有与值 x 和 y 对应的节点是堂兄弟节点时,才返回 true 。否则,返回 false。 示例: 示例 1: 输入:root = [1,2,3,4], x = 4, y = 3 输出:false

By Ne0inhk
1239.串联字符串的最大长度 关于字符串的回溯算法!

1239.串联字符串的最大长度 关于字符串的回溯算法!

题目: 给定一个字符串数组 arr,字符串 s 是将 arr 某一子序列字符串连接所得的字符串, 如果 s 中的每一个字符都只出现过一次,那么它就是一个可行解。 请返回所有可行解 s 中最长长度。 提示: 1 <= arr.length <= 16 1 <= arr[i].length <= 26 arr[i] 中只含有小写英文字母 示例: 示例 1: 输入:arr = ["un","iq","ue"] 输出:4 解释:所有可能的串联组合是

By Ne0inhk