为什么重写equals时必须重写hashCode方法?

原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
    }

/*返回哈希码,String的哈希码计算方式为s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]*/
public int hashCode() {
    int h = hash;
    if (h == 0) {
        int off = offset;
        char val[] = value;
        int len = count;

            for (int i = 0; i < len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h;
    }

那为什么在重写equals方法时都要重写hashCode方法呢:
首先equals与hashcode间的关系是这样的:

1、如果两个对象相同(即用equals比较返回true),那么它们的hashCode值一定要相同;

2、如果两个对象的hashCode相同,它们并不一定相同(即用equals比较返回false)

自我的理解:

由于为了提高程序的效率才实现了hashcode方法,先进行hashcode的比较,如果不同,那没就不必在进行equals的比较了,这样就大大减少了equals比较的次数,这对比需要比较的数量很大的效率提高是很明显的,一个很好的例子就是在集合中的使用;

我们都知道java中的List集合是有序的,因此是可以重复的,而set集合是无序的,因此是不能重复的,那么怎么能保证不能被放入重复的元素呢,但靠equals方法一样比较的话,如果原来集合中以后又10000个元素了,那么放入10001个元素,难道要将前面的所有元素都进行比较,看看是否有重复,欧码噶的,这个效率可想而知,因此hashcode就应遇而生了,java就采用了hash表,利用哈希算法(也叫散列算法),就是将对象数据根据该对象的特征使用特定的算法将其定义到一个地址上,那么在后面定义进来的数据只要看对应的hashcode地址上是否有值,那么就用equals比较,如果没有则直接插入,只要就大大减少了equals的使用次数,执行效率就大大提高了。

继续上面的话题,为什么必须要重写hashcode方法,其实简单的说就是为了保证同一个对象,保证在equals相同的情况下hashcode值必定相同,如果重写了equals而未重写hashcode方法,可能就会出现两个没有关系的对象equals相同的(因为equal都是根据对象的特征进行重写的),但hashcode确实不相同的。

原文地址:https://www.cnblogs.com/cuijiade/p/9487082.html

时间: 2024-10-10 13:03:13

为什么重写equals时必须重写hashCode方法?的相关文章

为什么重写equals时必须重写hashCode方法?(转发+整理)

为什么重写equals时必须重写hashCode方法? 原文地址:http://www.cnblogs.com/shenliang123/archive/2012/04/16/2452206.html 首先我们先来看下String类的源码:可以发现String是重写了Object类的equals方法的,并且也重写了hashcode方法 public boolean equals(Object anObject) { if (this == anObject) { return true; } i

java中为什么重写equals时必须重写hashCode方法?

在上一篇博文Java中equals和==的区别中介绍了Object类的equals方法,并且也介绍了我们可在重写equals方法,本章我们来说一下为什么重写equals方法的时候也要重写hashCode方法. 先让我们来看看Object类源码 /** * Returns a hash code value for the object. This method is * supported for the benefit of hash tables such as those provided

为什么重写equals时必须重写hashCode方法

1.hashCode的作用是获取哈希码,也称为散列码,是确定该对象在哈希表中的索引位置,是一个int类型的数值. 2.如果两个对象相等,那么hashCode一定相等,但是hashCode相等不代表两个对象相等. 3.以HashSet为例,当HserhSet加入新的对象时,首先会判断新对象的hashCode是否与集合内对象的hashCode相同,如果不相同则进行添加,相同则再次用equals进行判断两个对象是否真的相等,这样就减少了equals的调用,提高执行效率. 4.equals的作用是判断两

为什么重写equals后要重写hashCode

equals和hashCode的关系 要搞清楚题目中的问题就必须搞明白equals方法和hashCode方法分别是什么,和诞生的原因,当搞明白了这一点其实题目就不算是个问题了,下面我们来探讨分别探讨一下两者代表的意义. hashCode 笔者看到很多地方都对hashCode有两个误解 对象默认的hashCode是对象的地址. 默认的equals会先比较对象的hashCode,如果hashCode相同则代表两个对象是同一个对象. 在这里笔者先给出这两个问题的结论,后面会给出证明. hashCode

Java的重写equals但不重写hashCode方法的影响

首先,说下equals和hashCode的关系.JDK API中关于Object类的equals和hashCode方法中说过,总结起来就是两句话:equals相等的两个对象的hashCode也一定相等,但hashCode相等的两个对象不一定equals相等. hashCode类似于一个位置值(不叫地址值,是想把每个对象所在的位置做地址值),HashSet.HashMap等集合类中常会用到. 上图中假设是对象在内存中的模型,则7—c就是位置值即hashCode,而71—74就是地址值.所以x,y和

Effective Item 6 - 覆盖equals方法时不要忘记hashCode方法

任何覆盖了equals方法的类都需要覆盖hashCode方法. 忽视这一条将导致类无法与基于散列的数据结构一起正常工作,比如和HashMap.HashSet和Hashtable. 下面是hashCode相关规范: ·在程序执行期间,只要对象的equals方法的比较操作所用到的信息没有被修改,那么对这个对象调用多少次hashCode,起结果必须始终如一地返回同一个证书. 如果是同一个程序执行多次,每次调用的结果可以不一致. ·如果两个对象根据equals方法比较是相等的,那么两个对象的hashCo

编写高质量代码改善C#程序的157个建议——建议12: 重写Equals时也要重写GetHashCode

建议12: 重写Equals时也要重写GetHashCode 除非考虑到自定义类型会被用作基于散列的集合的键值:否则,不建议重写Equals方法,因为这会带来一系列的问题. 如果编译上一个建议中的Person这个类型,编译器会提示这样一个信息: “重写 Object.Equals(object o)但不重写 Object.GetHashCode()” 如果重写Equals方法的时候不重写GetHashCode方法,在使用如FCL中的Dictionary类时,可能隐含一些潜在的Bug.还是针对上一

第10项:重写equals时请遵守通用约定

??重写equals方法看起来似乎很简单,但是有许多重写方式会导致错误,而且后果非常严重.最容易避免这类问题的办法就是不覆盖equals方法,在这种情况下,类的每个实例都只能与它自身相等.如果满足了以下任何一个条件,那就是正确的做法: 类的每个实例都是唯一的. 对于代表活动实体而不是值(value)的类来说确实如此,例如Thread.Object提供的equals实现对这些类具有完全正确的行为(The equals implementation provided by Object has ex

为什么重写equals()就必须重写hashCode(),什么情况下可以不重写hashCode()

(1)当所在类不使用HashSet.Hashtable.HashMap等散列集合进行存储的时候,可以不使用hashcode. (2)当在HashSet.Hashtable.HashMap中使用该类时,hashcode和equals是有关系的,hashcode和equals需要同时重写才能保证元素的唯一性.hashcode是为了提高散列结构存储中查找的效率,在线性表中没有作用. ==操作符比较的是值[变量(栈)内存中存放的对象的(堆)内存地址]. equal用于比较两个对象的值是否相同[不是比地址