可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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().
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
Actual Java language equals method
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?
Aren't hashCode and address one and same?
Also, is hashCode compared when we say a==b or something else?
回答1:
String
class has overridden the equals()
method . Please follow the String#equals() documentation.
a.equals(b) has returned true, meaning the condition a==b is satisfied
This is the default implementation of equals()
in the Object
class , String
class 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.
Aren't hashCode and address one and same?
Not necessarily , for further reading on hashCode().
回答2:
No, Hashcode and address aren't the same.
Because a==b is not comparing hashcodes.
Yes, something else is compared when we say 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".
回答3:
The ==
operator in Java compares object references to see if they refer to the same object. Because your variables a
and b
refer to different objects, they are not equal according to ==
.
And the hashCode
method doesn't return the address in String
, because that class has overridden hashCode
.
Additionally, the equals
method has been implemented in String
to compare the contents of the strings; that's why a.equals(b)
returns true
here.
回答4:
a.equals(b) is different from a==b.
a.equals(b) checks if two objects are equals based on equals() implementation.
a==b checks if two objects have same reference.
If a==b is true then a.equals(b) must be true because they are referencing to the same object but not vice-versa.
回答5:
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.
回答6:
Hashcode for an object is meant to be overridden.
For String class the formula used is as follows:
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.
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
int hashcode(){
return 10;
}
This is a valid implementation but it is also the worst possible one. Read about why.
回答7:
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.
So, no, hashes and object references are not the same thing.
回答8:
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