当我覆盖equals()方法时,为什么要覆盖hashCode()?

bra*_*boy 29 java equals hashcode

好吧,我从许多地方和消息来源得知,每当我覆盖equals()方法时,我都需要覆盖hashCode()方法.但请考虑以下代码

package test;

public class MyCustomObject {

    int intVal1;
    int intVal2;

    public MyCustomObject(int val1, int val2){
        intVal1 = val1;
        intVal2 = val2;
    }

    public boolean equals(Object obj){
        return (((MyCustomObject)obj).intVal1 == this.intVal1) && 
                (((MyCustomObject)obj).intVal2 == this.intVal2);
    }

    public static void main(String a[]){
        MyCustomObject m1 = new MyCustomObject(3,5);
        MyCustomObject m2 = new MyCustomObject(3,5);
        MyCustomObject m3 = new MyCustomObject(4,5);

        System.out.println(m1.equals(m2));
        System.out.println(m1.equals(m3));
    }
}
Run Code Online (Sandbox Code Playgroud)

这里输出是真的,完全按照我想要的方式错误,我根本不关心覆盖hashCode()方法.这意味着hashCode()覆盖是一个选项而不是每个人都说的强制选项.

我想要第二次确认.

DVK*_*DVK 32

它适用于您,因为您的代码不使用任何需要hashCode()API的功能(HashMap,HashTable).

但是,您不知道您的类(可能不是一次性写入)稍后将在确实将其对象用作哈希键的代码中调用,在这种情况下,事情将受到影响.

根据Object类文档:

hashCode的一般契约是:

  • 每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象上的equals比较中使用的信息.从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致.

  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果.


Den*_*s C 11

因为HashMap/Hashtable将首先通过hashCode()查找对象.

如果它们不相同,则hashmap将断言对象不相同并且返回不存在于地图中.


pol*_*nts 5

之所以不需要@Override或两者都是因为它们与API的其他部分相互关联的方式.

你会发现,如果你把m1进入HashSet<MyCustomObject>的话,就不会contains(m2).这是不一致的行为,可能会导致很多错误和混乱.

Java库具有大量功能.为了使他们的工作你,你需要遵守游戏规则,并确保equalshashCode一致是最重要的一个.