JAVA之为什么重写equals时要重写hashcode

首先,如果是自定义的类重写equals后可以实现逻辑的比较是否相等。

但是在用哈希结构作为储存的类中会先用hashcode进行比较,而hashcode会根据对象的地址和字段生成一个散列值,而逻辑相等的对象地址不一样,所以如果业务希望逻辑相等即为相等的话就需要先重写hashcode。

主方法:

package com.company;

import java.util.*;

public class Main {

   public static void main(String[] args) {
       //String类型已经重写了equals,只会比较字符串是否相等,而对象的equals会加入对象地址进行比较
        String name1 = "Tom";
        String name2 = new String("Tom");
        System.out.println("```````````String比较`````````````");
        System.out.println("地址比较:" + (name1 == name2));
        System.out.println("对象比较:"+ name1.equals(name2));
        System.out.println("`````````````````````````````````\n");

        System.out.println("````````未重写equals前比较````````");
        OldPerson a = new OldPerson(1996001002,"奥巴马"); //id为身份证
        OldPerson b = new OldPerson(1996001002,"奥巴马"); //id为身份证
        System.out.println("对象比较"+ a.equals(b));
        //HashSet是哈希结构,会先调用hashcode()判定,此时a和b的地址不同,认为是两个不同的值,可以插入
        Set<OldPerson> set = new HashSet<>();
        set.add(a);
        set.add(b);
        for(OldPerson value: set){
           System.out.println(value.name);
        }
        System.out.println("```````````````````````````````````\n");


        System.out.println("````````重写equals后比较````````");
        Person c = new Person(1996001002,"奥巴马"); //id为身份证
        Person d = new Person(1996001002,"奥巴马"); //id为身份证
        System.out.println("对象比较"+ c.equals(d));
        Set<Person> set1 = new HashSet<>();
        set1.add(c);
        set1.add(c);
        set1.add(d);
        for(Person value: set1){
           System.out.println(value.name);
        }
        System.out.println("```````````````````````````````````\n");
    }

}

 运行结果:

显然,改写equals后,只能把一个奥巴马加入到列表中。

附表:

Person类:

package com.company;

public class Person {
    public int id ;
    public String name;
    public Person(int id ,String name){
        this.id = id ;
        this.name = name ;
    }

    @Override
    public boolean equals(Object obj){
        if(this == obj){
            return true;//地址相等  ==比较的是地址
        }
        if(obj == null){
            return false;//非空性:对于任意非空引用x,x.equals(null)应该返回false。
        }
        if(obj instanceof Person){
            Person other = (Person) obj;
            //JAVA已把String类的equals方法改为纯字符比较
            if(this.id == other.id && this.name.equals(other.name)){
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        return  id * 31 + name.hashCode() ;
    }
}

 OldPerson类

package com.company;

public class OldPerson {
    public int id ;
    public String name;
    public OldPerson(int id ,String name){
        this.id = id ;
        this.name = name ;
    }
}
发布了14 篇原创文章 · 获赞 1 · 访问量 247

猜你喜欢

转载自blog.csdn.net/qq_41976749/article/details/104924941