我很困惑哈希码和等于怎么样 - 为什么用相同参数创建的两个对象彼此不相等?

s-k*_*rek 0 java equals object hashcode

我正在努力深入理解Java,我正在尝试比较相同的对象.

我创建了两个具有相同值的字符串对象,但分配给了不同的变量.事实证明它们具有相同的哈希码.

之后,我创建了表示person的简单类,并使用传递给构造函数的相同参数创建了此类的两个实例.原来他们有不同的哈希码.

现在我很困惑它是如何工作的.你能解释一下吗?

我的代码:

 public static class Person {

        public String name;
        public String lastName;

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

    public static void main(String[] args) {

        String s1 = new String("foo");
        String s2 = new String("foo");
        System.out.println("String1 hashcode: " + s1.hashCode());
        System.out.println("String2 hashcode: " + s2.hashCode());
        System.out.println("Is String1 equal to String2?: " + s1.equals(s2));

        Person p1 = new Person("John", "Doe");
        Person p2 = new Person("John", "Doe");
        System.out.println("Person1 hashcode: " + p1.hashCode());
        System.out.println("Person2 hashcode: " + p2.hashCode());
        System.out.println("Is Person1 equal to Person2?: " + p1.equals(p2));

    }
}
Run Code Online (Sandbox Code Playgroud)

我的输出:

String1 hashcode: 101574
String2 hashcode: 101574
Is String1 equal to String2?: true
Person1 hashcode: 325040804
Person2 hashcode: 1173230247
Is Person1 equal to Person2?: false
Run Code Online (Sandbox Code Playgroud)

rge*_*man 9

hashCode方法String仅根据字符串的内容计算哈希码.

返回此字符串的哈希码.String对象的哈希码计算为

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
Run Code Online (Sandbox Code Playgroud)

但是,您尚未声明hashCode方法Person,因此它从中Object继承该方法.

尽可能合理,Object类定义的hashCode方法确实为不同的对象返回不同的整数.

如果一个类没有覆盖hashCode,那么我们应该期望不同对象的不同哈希码,而不管对象的内容如何.

比如String,您可以定义自己的hashCode方法,Person仅根据其内容确定哈希码.

您还应该覆盖,equals(Object)以便Person类定义Person实例彼此相等的方式; 必须始终如一地定义这两种方法:

hashCode的一般契约是:

  • 每当在执行Java应用程序期间多次在同一对象上调用它时,hashCode方法必须始终返回相同的整数,前提是不修改对象上的equals比较中使用的信息.从应用程序的一次执行到同一应用程序的另一次执行,该整数不需要保持一致.
  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果.
  • 如果两个对象根据equals(java.lang.Object)方法不相等,则不需要在两个对象中的每一个上调用hashCode方法必须生成不同的整数结果.但是,程序员应该知道为不等对象生成不同的整数结果可能会提高哈希表的性能.