11

我正在深入研究 Java 的基础知识。我从这篇文章中推断,Java 的“equals”方法意味着,如果两个对象相等,那么它们必须具有相同的 hashCode()。

这是我的例子。

public class Equals {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String a = new String("a");
        String b = new String("a");
        System.out.println("a.hashCode() "+a.hashCode());
        System.out.println("b.hashCode() "+b.hashCode());
        System.out.println(a == b);
        System.out.println(a.equals(b));
    }

}

输出:

a.hashCode() 97
b.hashCode() 97

实际的 Java 语言 'equals' 方法:

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

在我上面的示例中,a.equals(b)返回了 true,这意味着条件 'a==b' 得到满足。但是为什么在那个例子中'a==b'返回假?

hashCode 和 address 不是一回事吗?此外,当我们说“a==b”或其他内容时,是否比较了“hashCode”?

4

8 回答 8

14

该类String已覆盖该equals()方法。请遵循字符串 equals()文档。

a.equals(b) 已返回 true,表示满足条件 a==b

这是类中的默认实现equals()Object并且String类已经覆盖了默认实现。当且仅当参数不为 null 并且是表示与此对象相同的字符序列的 String 对象时,它才返回 true。

hashCode 和 address 不是一回事吗?

不必要。进一步阅读hashCode()

于 2013-04-18T17:18:28.983 回答
4

Java 中的==运算符比较对象引用以查看它们是否引用同一个对象。因为你的变量ab引用不同的对象,它们根据==.

并且该hashCode方法不会返回 中的地址String,因为该类已被覆盖hashCode

此外,该equals方法已实现String用于比较字符串的内容;这就是为什么a.equals(b)回到true这里。

于 2013-04-18T17:19:26.673 回答
3

不,哈希码和地址不一样。

因为 a==b 没有比较哈希码。

是的,当我们说 a==b 时,会比较其他东西。

(这也不是地址,真的,但它足够接近)。

此外,仅仅因为“相等的对象具有相等的哈希码”并不意味着“相等的哈希码意味着相等的对象”。

于 2013-04-18T17:17:50.483 回答
1

a.equals(b) 与 a==b 不同。

a.equals(b) 根据 equals() 实现检查两个对象是否相等。

a==b 检查两个对象是否具有相同的引用。

如果 a==b 为真,则 a.equals(b) 必须为真,因为它们引用的是同一个对象,反之则不然。

于 2013-04-18T17:18:51.387 回答
1

String 类覆盖了 Object 类的 equals() 方法的默认实现。您提供的 equals 方法代码不是来自 String 类,而是来自 Object 类,它被 String 类实现覆盖,它检查两个对象的内容是否相同。

于 2013-04-18T17:19:19.987 回答
1

对象的哈希码意味着被覆盖。

对于 String 类,使用的公式如下:

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

我鼓励您搜索为什么 31 被用作乘数而不是其他数字。

覆盖哈希码的一般经验法则是,对于不同的对象,哈希码应该尽可能不同。

为此,建议您在计算哈希值时考虑对象的每个重要字段。

注意:只是一个无关的思考(来源:Effective Java):考虑以下哈希码的实现

int hashcode(){
     return 10;
}

这是一个有效的实现,但它也是最糟糕的实现。阅读为什么。

于 2013-04-18T17:20:47.087 回答
0

A 和 B 是两个独立的对象,String由于hashCode(). ==只是检查左右两侧是否共享相同的参考。它不调用Object'sequals()方法。

所以,不,散列和对象引用不是一回事。

于 2013-04-18T17:20:46.283 回答
0
public class TestEquals {
    /**
     * @param args
     */
    public static void main(String[] args) {
        String a = new String("a"); 
        String b = new String("a");
        System.out.println("a.hashCode() " + a.hashCode());
        System.out.println("b.hashCode() " + b.hashCode());

        // Checks the reference which is something like the 
        // address & address is different from hash code which can be overriden
        System.out.println(a == b);

        // It returns true if and only if the argument is not null 
        // and is a String object that represents the same sequence 
        // of characters as this object. (String Implementation of equals)
        System.out.println(a.equals(b));
    }
}

输出:

a.hashCode() 97
b.hashCode() 97
false
true
于 2019-07-20T19:24:07.900 回答