java equals() 方法的工作原理

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16089282/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 21:52:39  来源:igfitidea点击:

How equals() method works

javaequals

提问by srk

I am digging into the basics of Java. I infer from this article, that java equals method means, if two objects are equal then they must have the same hashCode().

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

Here's my example.

这是我的例子。

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));

    }

}

output:
a.hashCode() 97
b.hashCode() 97
false
true

输出:
a.hashCode() 97
b.hashCode() 97
false
true

Actual Java language equals method

实际的 Java 语言 equals 方法

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

In my above example, a.equals(b) has returned true, meaning the condition a==b is satisfied. But then why a==b is returning false in that example?

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

Aren't hashCode and address one and same? Also, is hashCode compared when we say a==b or something else?

hashCode 和 address 不是一回事吗?另外,当我们说 a==b 或其他东西时,是否比较 hashCode ?

回答by NINCOMPOOP

Stringclass has overridden the equals()method . Please follow the String#equals()documentation.

String类已经覆盖了equals()方法。请遵循String#equals()文档。

a.equals(b) has returned true, meaning the condition a==b is satisfied

a.equals(b) 返回 true,意味着满足条件 a==b

This is the default implementation of equals()in the Objectclass , Stringclass has overridden the default implementation. 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.

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

Aren't hashCode and address one and same?

hashCode 和 address 不是一回事吗?

Not necessarily , for further reading on hashCode().

不一定,进一步阅读hashCode()

回答by CPerkins

No, Hashcode and address aren't the same.

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

Because a==b is not comparing hashcodes.

因为 a==b 不是比较哈希码。

Yes, something else is compared when we say a==b.

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

(that's not addresses either, really, but it's close enough).

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

Also, just because "equal objects have equal hashcodes" does not mean "equal hashcodes means equal objects".

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

回答by rgettman

The ==operator in Java compares object references to see if they refer to the same object. Because your variables aand brefer to different objects, they are not equal according to ==.

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

And the hashCodemethod doesn't return the address in String, because that class has overridden hashCode.

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

Additionally, the equalsmethod has been implemented in Stringto compare the contents of the strings; that's why a.equals(b)returns truehere.

此外,该equals方法已被实现String以比较字符串的内容;这就是a.equals(b)返回true这里的原因。

回答by prashant

Hashcode for an object is meant to be overridden.

对象的哈希码旨在被覆盖。

For String class the formula used is as follows:

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

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

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

I encourage you to search why 31 has been used as a multiplier and not some other number.

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

A general thumb rule for overriding hash code is that for different objects hash code should be different as far as possible.

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

To achieve this it is advisable that you take into account every significant field of an object while calculating the hash value.

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

Note: Just an unrelated food for thought (source : Effective Java): Consider the following implementation of hashcode

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

int hashcode(){
     return 10;
}

This is a valid implementation but it is also the worst possible one. Read about why.

这是一种有效的实现,但也是最糟糕的一种。阅读原因。

回答by IndoKnight

a.equals(b) is different from a==b.

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

a.equals(b) checks if two objects are equals based on equals() implementation.

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

a==b checks if two objects have same reference.

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

If a==b is true then a.equals(b) must be true because they are referencing to the same object but not vice-versa.

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

回答by Ankur Shanbhag

String class overrides the default implementation of the equals()method of the Object class. The equals method code that you have provided is not from String class but from the Object class, which is overridden be the String class implementation which checks if the contents of the two objects are same or not.

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

回答by Gru

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));
    }
}

Output:

输出:

a.hashCode() 97
b.hashCode() 97
false
true

回答by dcow

A and B are two separate objects that generate the same hash code because of String's implementation of hashCode(). ==just checks to see if the left and right sides share the same reference. It does not call an Object's equals()method.

A 和 B 是两个独立的对象,由于String的实现,它们生成相同的哈希码hashCode()==只需检查左侧和右侧是否共享相同的参考。它不会调用 anObjectequals()方法。

So, no, hashes and object references are notthe same thing.

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