欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

equals方法和hasCode方法,为什么重写equals()的时候要重写hasCode()?

程序员文章站 2022-04-19 17:36:55
...

equals()和hashCode()在面试的时候被问到的频率很高,equals()方法和hasCode()方法有什么关系?为什么重写equals()的时候要重写hasCode()?

equals和hasCode是Object类中的两个方法,Object类是所有类的父类

新建一个带有姓名和年龄的Person类

public class Person {
    private Integer age;
    private String name;

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }
}

 

实例化并调用equals方法进行比较

public static void main(String[] args) {
        Person person = new Person(11,"张三");
        Person person2 = new Person(11,"张三");
        System.out.println(person.equals(person2)); // 输出结果为false
 }

这是实际调用了Object类中的equals方法,它是用 " == " 进行判断的," == " 是判断两个对象的地址值是否相同,如果地址值相同,就认为是同一个对象。

所以equals方法是判断两个对象是否相同。

Object类中的equals方法:

public boolean equals(Object obj) {
        return (this == obj);
    }

但是我们在项目开发中,一般如果两个对象的属性相同,我们就认为他们是相等的,所以我们会重写equals方法,只判断他们的属性值是否相同,就是说只要年龄和姓名相等,我们就认为是同一个人

重写后的equals方法:

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof EqualsPerson)) return false;
        EqualsPerson that = (EqualsPerson) o;
        return age.equals(that.age) &&
                name.equals(that.name);
    }

进行重写后,再次调用equals方法进行比较

public static void main(String[] args) {
        // 重写equals()之后
        EqualsPerson equalsPerson = new EqualsPerson(11,"张三");
        EqualsPerson equalsPerson1 = new EqualsPerson(11,"张三");
        System.out.println(equalsPerson.equals(equalsPerson1));  // 输出结果为true
        
}

那我们重写equals()之后的结果都为true了,为什么还要重写hashCode()?

因为在项目中如果两个对象相等我们一般会就行去重操作,把两个对象放一个set里

public static void main(String[] args) {
        Person person = new Person(11, "张三");
        Person person2 = new Person(11, "张三");
        Set<Person> personSet = new HashSet<>();
        personSet.add(person);
        personSet.add(person2);
        System.out.println(person.equals(person2)); //输出结果为true
        for (Person personItem : personSet) {
            //输出结果为: Person{age=11, name='张三'}Person{age=11, name='张三'}
            System.out.print(personItem.toString());
        }
    }

看输出结果set中还是两个对象,去重失败了。

年轻人不能头太铁,要不我们试试也重写一下hashCode()呢?

hashCode() 的作用:

主要是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用是确定该对象在哈希表中的索引位置。

没有重写之前,我们看一下hashCode()的返回值

public static void main(String[] args) {
        Person person = new Person(11, "张三");
        Person person2 = new Person(11, "张三");
        System.out.println(person.hashCode());  // 输出结果为356573597
        System.out.println(person2.hashCode());  // 输出结果为1735600054
}

object类中的 hashCode()方法

public native int hashCode();

我们可以看到hashCode()的返回值是不一样的,

重写hashCode方法:

@Override
    public int hashCode() {
        return Objects.hash(age, name);
}

我们看一下重写之后,hashCode()的返回值

public static void main(String[] args) {
        Person person = new Person(11, "张三");
        Person person2 = new Person(11, "张三");
        System.out.println(person.hashCode());  // 输出结果为776191
        System.out.println(person2.hashCode());  // 输出结果为776191
    }

我们在把两个对象放入set去重

public static void main(String[] args) {
        Person person = new Person(11, "张三");
        Person person2 = new Person(11, "张三");
        Set<Person> personSet = new HashSet<>();
        personSet.add(person);
        personSet.add(person2);
        System.out.println(person.equals(person2)); //输出结果为true
        for (Person personItem : personSet) {
            //输出结果为: Person{age=11, name='张三'}
            System.out.print(personItem.toString());
        }
    }

查看输出结果,去重成功,可以看出set去重时候会进行hash,hash相同的时候才可以去重

总结:

1.equals和hasCode是Object类中的两个方法,因为在Object类中的equals方法是用"=="进行判断,即地址值是否相同,  在业务开发中,如果两个对象的值相等,我们一般就认为他们是同一对象,所以我们都会重写equals方法。hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数,这个哈希码的是用来确认该对象在哈希表中的索引位置。

2.hashCode() 在散列表中才有用,就是说我们会在HashSet, Hashtable, HashMap等等这些本质是散列表的数据结构中,用到该类的时候,才需要重写hashCode()方法,比如说创建该类HashSet集合,set是根据hash进行去重的

3.如果两个对象相等,那么它们的hashCode()值一定相同,但是如果两个对象hashCode()相等,一定相等吗? 

答:不一定,因为两个不同的键值对,哈希值相等,可能是发生了哈希冲突。

 

欢迎在评论区留言交流,喜欢的小伙伴记得点赞。感谢阅读!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

相关标签: java基础