重写hashcode 与 equals方法

文章目录

重写hashcode 与 equals方法

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return  id == user.id &&
                age == user.age &&
                Objects.equals(name, user.name);
    }

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

Why同时重写:

官方约定:

  • 在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,那么,对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。在同一个应用程序的多次执行过程中,这个整数可以不同,即这个应用程序这次执行返回的整数与下一次执行返回的整数可以不一致。
  • 如果两个对象根据equals(Object)方法是相等的,那么调用这两个对象中任一个对象的hashCode方法必须产生同样的整数结果。
  • 如果两个对象根据equals(Object)方法是不相等的,那么调用这两个对象中任一个对象的hashCode方法,不要求必须产生不同的整数结果。然而,程序员应该意识到这样的事实,对于不相等的对象产生截然不同的整数结果,有可能提高散列表(hash table)的性能。
通常情况下,当我们需要比较两个对象的时候,希望比较的是两个对象的某些值是否相等,而不是比较两个对象是否引用于同一个地址。

1. 不重写的情况:

当我们不重写hashcode与equals方法时,默认使用 java 提供的 java.lang.Object 下的 hashCode()和equals() 方法。

默认比较:主要是对非空对象的引用地址的判断,地址一致则返回true
重写hashcode 与 equals方法重写hashcode 与 equals方法

1.1 两者关系

(1)当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true
(2)当obj1.hashCode() == obj2.hashCode()为false时,obj1.equals(obj2)必须为false

2. 只重写equals的情况:

  • 如果我们对一个对象重写了equals 方法,意味着只要对象的成员变量值都相等那么equals 就返回true ,但在不重写 hashcode 方法的情况下,当我们重新 new 了一个新对象。
  • 此时,当原对象.equals(新对象)等于true时,两者的 hashcode 却是不一样的,由此会产生了理解的不一致,也违反了equals 与 hashcode的约定规则。

2.1 不重写导致的结果案例:

  • 在不重写hashcode的情况下,如果 hashset存储两个引用不同但值相同的对象,此时hashcode返回false,认为后者与前者不重复,则会重新 newNode() 创建一个新节点将重复的值添加到集合中,意味着不可重复的单列集合中出现了两个值一样的对象,导致混淆。(假设没有重写)
上一篇:2021-06-13


下一篇:hashCode 的值是怎么生成的?对象内存地址吗?