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

Posted dashenaichicha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么重写equals()就必须重写hashCode(),什么情况下可以不重写hashCode()相关的知识,希望对你有一定的参考价值。

  (1)当所在类不使用HashSet、Hashtable、HashMap等散列集合进行存储的时候,可以不使用hashcode。

  (2)当在HashSet、Hashtable、HashMap中使用该类时,hashcode和equals是有关系的,hashcode和equals需要同时重写才能保证元素的唯一性。hashcode是为了提高散列结构存储中查找的效率,在线性表中没有作用。

  ==操作符比较的是值【变量(栈)内存中存放的对象的(堆)内存地址】。

  equal用于比较两个对象的值是否相同【不是比地址】。

  注意:Object类中的equals方法和“==”是一样的,没有区别,而String类,Integer类等一些类,是重写了equals方法,才使得equals和“==不同”。对于基础数据类型来说,没有重写equals方法,故两者是一样。

①equals()方法:

public class BaseTypeDemo {
    public static void main(String[] args) {
        //对于基本类型的变量。"=="和"equal"的区别
        int t1=57;
        int t2=67;
        int t3=124;
        int t4=124;
        //“==”对于基本数据类型,判断两个变量的值是否相等。
        Boolean result1=(t1==t2);
        Boolean result2=((t1+t2)==t3);
        Boolean result3=(t3==t4);
        System.out.println("【t1==t2】"+result1);
        System.out.println("【(t1+t2)=t3】"+result2 );
        System.out.println("【t3=t4】"+result3);
 
        //“equal”不能用于基本数据类型。只能用于类变量。对于基本数据类型要用其包装类。
        Integer i1=new Integer(t1);
        Integer i2=new Integer(t2);
        Integer i3=new Integer(t3);
        Integer i4=new Integer(t4);
 
 
        Boolean ri1=i1.equals(i2);
        Boolean ri2=i3.equals(i1+i2);
        Boolean ri3=i3.equals(i4);
 
        System.out.println("【i1.equals(i2)】"+ri1);
        System.out.println("【i3.equals(i1+i2)】"+ri2);
        System.out.println("【i3.equals(i4)】"+ri3);
    }
}
/**
*运行结果
【t1==t2】false
【(t1+t2)=t3】true
【t3=t4】true
【i1.equals(i2)】false
【i3.equals(i1+i2)】true
【i3.equals(i4)】true
*/

  String类,是重写了equals方法,才使得equals和“==不同”。

public class StringDemo {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = new String("Hello");
        String str3 = str2; // 引用传递
        System.out.println(str1 == str2); // false
        System.out.println(str1 == str3); // false
        System.out.println(str2 == str3); // true
        System.out.println(str1.equals(str2)); // true
        System.out.println(str1.equals(str3)); // true
        System.out.println(str2.equals(str3)); // true
    }
}

  重写equals()方法时需要把类的字段的那些在实际对象中进行传入比较,保证是比较的对象的“内容”。而如果不重写此时的hashCode()的话,就会出现如果是相同的一个对象,但是我修改了这个对象的某个属性,比如在hashMap中保存的这个对象,但是此时我再想get到它就只能返回一个空值null了,因为hash值是与对象的字段属性相关联的,此时由于修改了这些字段属性,所以对应的对象的哈希值也发生了改变,再用此时的哈希值去取对象是取不到的。

以上是关于为什么重写equals()就必须重写hashCode(),什么情况下可以不重写hashCode()的主要内容,如果未能解决你的问题,请参考以下文章

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

一文就带你搞懂✨为什么重写 equals 时必须重写 hashCode 方法?

重写equals就必须重写hashCode的原理分析

为什么重写equals后要重写hashCode

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

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