На дворе 2022 год, и не будет никого, кто не смог бы понятно объяснить метод hashCode.

1. Введите метод hashCode

  1. hashCode()Роль состоит в том, чтобы получить хэш-код, также известный как хэш-код, он фактически возвращает целое число. Роль этого хэш-кода заключается в определении позиции индекса объекта в хэш-таблице.

  2. hashCode()Определено в JDK Object.java, что означает, что любой класс в Java содержит hashCode()функции .

  3. Хеш-таблица хранит пары ключ-значение, и ее характеристика заключается в том, что соответствующее «значение» может быть быстро извлечено по «ключу». Здесь используются хэш-коды! (Вы сможете быстро найти нужный объект).

2. Зачем нужен метод hashCode?

В процессе написания программ определение, являются ли два объекта одинаковыми, является очень распространенной и часто встречающейся проблемой. hashCode()Метод используется для повышения скорости сравнения двух объектов.

Давайте возьмем «Как HashSet проверяет наличие дубликатов» в качестве примера, чтобы проиллюстрировать, почему существует hashCode :

  • HashSetКогда вы добавляете объект , HashSet сначала вычислит hashcodeзначение объекта, чтобы определить, куда добавляется объект, а также сравнит его со hashcodeзначениями совпадения нет hashcode, HashSetон будет считать, что объект не появляется повторно.

  • Но если найдены объекты с одинаковым hashcodeзначением , то вызывается метод equals(), чтобы проверить hashcode, действительно ли равные объекты одинаковы. Если они совпадают, HashSetоперация соединения не будет успешной. Если он отличается, он будет перефразирован в другом месте.

  • Таким образом, мы значительно уменьшаем equalsколичество раз и, соответственно, значительно улучшаем скорость выполнения.

3. Какая связь между методами hashCode() и equals()?

Java определяет метод equals() и метод hashCode() следующим образом:

  • Несколько вызовов метода hashCode() для одного и того же объекта всегда возвращают одно и то же целочисленное значение.
  • 如果 a.equals(b),则一定有 a.hashCode() 一定等于 b.hashCode()。
  • 如果 !a.equals(b),则 a.hashCode() 不一定等于 b.hashCode()。此时如果 a.hashCode() 总是不等于 b.hashCode(),会提高 hashtables 的性能。
  • a.hashCode()==b.hashCode() 则 a.equals(b) 可真可假
  • a.hashCode()!= b.hashCode() 则 a.equals(b) 为假。

上面结论简记:

  • 如果两个对象 equals,Java 运行时环境会认为他们的 hashCode 一定相等。
  • 如果两个对象不 equals,他们的 hashCode 有可能相等。
  • 如果两个对象 hashCode 相等,他们不一定 equals。
  • 如果两个对象 hashCode 不相等,他们一定不 equals。

4、为什么重写 equals 方法必须重写 hashcode 方法 ?

  • 我们上面讲解到 如果 两个对象 equals 的话,那么它们的 hashCode 值必然相等。如果只重写了 equals 方法,而不重写 hashCode 的方法,会造成 hashCode 的值不同,而 equals 方法判断出来的结果为true

  • 在Java中的一些容器中,不允许有两个完全相同的对象,插入的时候,如果判断相同则会进行覆盖。这时候如果只重写了 equals 的方法,而不重写 hashCode 的方法,Object中 hashCode 是根据对象的存储地址转换而形成的一个哈希值。这时候就有可能因为没有重写 hashCode 方法,造成相同的对象散列到不同的位置而造成对象的不能覆盖的问题。

例如

  • Dog类
package com.xiao;

/**
 * @author :小肖
 * @date :Created in 2022/3/11 14:42
 */
public class Dog {

    private String name;

    private Integer age;


    public Dog() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

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


    @Override
    public boolean equals(Object obj) {
        if(obj.getClass() != getClass()){
            return false;
        }
        Dog dog = (Dog) obj;
        if(dog.getAge() == age && dog.getName().equals(name)){
            return true;
        }
        return false;
    }
}

复制代码
  • 测试类
import com.xiao.Dog;

public class Test {

    public static void main(String[] args) {
        Dog dog = new Dog("小旺",2);
        Dog dog1 = new Dog("小旺",2);
        System.out.println("equals结果:" + dog.equals(dog1));
        System.out.println("dog 的 hashCode 值是否等于 dog1 的 hashCode 值:" +(dog.hashCode() == dog1.hashCode()));
    }
}
复制代码
  • 测试结果
equals结果:true
dog 的 hashCode 值是否等于 dog1 的 hashCode 值:false
复制代码

рекомендация

отjuejin.im/post/7085298943063490568