又到了金三银四,准备了几天Java八股文,发现自己差挺多,死记不是个办法,最近在读《认知觉醒》,里面提到关于知识的稳固其实还是在于输出,所以我想着趁着掘金有活动,我自己也做个记录,至于为什么选择这个标题,是因为这个内容我背了好多次,想通过自己的理解写下来,看看我到底是理解了多少,虽然简单,希望大家不吝批评和指正,那对我就很有帮助了。
hashcode和equals是java中,object类的默认方法,由于object是基类,所以我们使用的类也就有这个方法,看源码注释如下:
/**
* Returns a hash code value for the object. This method is
* supported for the benefit of hash tables such as those provided by
* {@link java.util.HashMap}.
* <p>
* The general contract of {@code hashCode} is:
* <ul>
* <li>Whenever it is invoked on the same object more than once during
* an execution of a Java application, the {@code hashCode} method
* must consistently return the same integer, provided no information
* used in {@code equals} comparisons on the object is modified.
* This integer need not remain consistent from one execution of an
* application to another execution of the same application.
* <li>If two objects are equal according to the {@code equals(Object)}
* method, then calling the {@code hashCode} method on each of
* the two objects must produce the same integer result.
* <li>It is <em>not</em> required that if two objects are unequal
* according to the {@link java.lang.Object#equals(java.lang.Object)}
* method, then calling the {@code hashCode} method on each of the
* two objects must produce distinct integer results. However, the
* programmer should be aware that producing distinct integer results
* for unequal objects may improve the performance of hash tables.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined by
* class {@code Object} does return distinct integers for distinct
* objects. (This is typically implemented by converting the internal
* address of the object into an integer, but this implementation
* technique is not required by the
* Java™ programming language.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
使用Idea的通义插件翻译了下,如下: 以上是Java中Object类的hashCode方法的文档注释,解释了hashCode方法的契约和实现要求。hashCode方法用于返回对象的哈希码值,主要用于支持哈希表(如HashMap)。其核心要求包括:同一对象多次调用hashCode应返回相同值;若两个对象equals相等,则它们的hashCode也必须相等;但hashCode不要求不同对象返回不同值,不过不同对象的哈希码不同有助于提高哈希表性能。
从以上这段文字,我们知道了同一对象多次调用hashCode应返回相同值;若两个对象equals相等,则它们的hashCode也必须相等,那这是为什么呢?
这里面提到了equals,那我们先看看equals的方法内部,很简单。
public boolean equals(Object obj) {
return (this == obj);
}
我们知道默认的==就是比较地址,但是类生成的每个实例都是不一样的,因为内存地址是不一样的,所以如果不重写,实际每个实例之间都是不同的。
但是我们代码的逻辑有时候不一定是说地址不一样,实例就不一样,比如两个字符串,都是new String("hello world"),如果String未重写这2个方法,那么地址肯定不一样,所以比较的话也就不相等,但是我们实际应用时是想让这2个比较起来是相等的,所以重写equals方法,此时比较就不是基于地址,而是基于内容,既然重写了equals,如果不重写hashcode就会造成逻辑不一致,因为两个一样的实例,其hashcode应该是相等的,所以也得重写hashcode方法使其保持一致。这就符合了这句话:若两个对象equals相等,则它们的hashCode也必须相等;
再看下一句话,说不要求不同的对象返回不同的hashcode
,因为hashcode是经过一系列的计算得出来的,如果重写了hashcode,难免会出现计算出相同的结果,但是这不代表这2个对象就是相同的,所以重写hashcode不强制要求重写equals。
但是又提到一句话说,不过不同对象的哈希码不同有助于提高哈希表性能
,我们假设个极端情况,如果不同的对象都是同一个哈希码,那么假如从hashmap中取数据,此时的时间复杂度就是O(n)了,而不是一般情况下的O(log n),甚至另一个极端情况下,如果不存在hash冲突,此时的时间复杂度就是O(1)了。
以上就是我的理解,如有补充,欢迎大家评论区指出。感谢~