我正在深入研究Java的基础知识 . 我从这个article推断,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));
}
}
output:
a.hashCode()97
b.hashCode()97
假
真正
实际Java语言等于方法
public boolean equals(Object obj) {
return (this == obj);
}
在上面的例子中,a.equals(b)返回true,意味着满足条件a == b . 但那么为什么a == b在这个例子中返回false?
hashCode和地址不一样吗?另外,当我们说a == b或其他什么时,hashCode是否被比较?
7 回答
String
类已重写equals()
方法 . 请遵循String#equals()文档 .a.equals(b)返回true,表示满足条件a == b
这是
Object
类中equals()
的默认实现,String
类已覆盖默认实现 . 当且仅当参数不为null并且是表示与此对象相同的字符序列的String对象时,它才返回true .hashCode和地址不一样吗?
不一定,进一步阅读hashCode() .
No, Hashcode and address aren't the same.
因为a == b不比较哈希码 .
Yes, something else is compared when we say a==b.
(这也不是地址,真的,但它足够接近) .
Also, just because "equal objects have equal hashcodes" does not mean "equal hashcodes means equal objects".
Java中的
==
运算符比较对象引用以查看它们是否引用同一对象 . 因为您的变量a
和b
引用不同的对象,所以它们根据==
不相等 .并且
hashCode
方法不会返回String
中的地址,因为该类具有overridden hashCode .此外,equals方法已在
String
中实现,以比较字符串的内容;这就是a.equals(b)
在这里返回true
的原因 .a.equals(b)与a == b不同 .
a.equals(b)基于equals()实现检查两个对象是否等于 .
a == b检查两个对象是否具有相同的引用 .
如果a == b为真,则a.equals(b)必须为true,因为它们引用同一个对象,反之则不然 .
String类 overrides the default implementation of the equals() Object类的方法 . 您提供的equals方法代码不是来自String类,而是来自Object类,它被重写为String类实现 checks if the contents of the two objects are same or not.
对象的Hashcode意味着被覆盖 .
对于String类,使用的公式如下:
s [0] * 31 ^(n-1)s [1] * 31 ^(n-2)... s [n-1]
我鼓励你搜索为什么31被用作乘数而不是其他数字 .
覆盖哈希码的一般拇指规则是,对于不同的对象,哈希码应尽可能不同 .
为实现此目的,建议您在计算哈希值时考虑对象的每个重要字段 .
注意:只是一个无关的思考(来源:Effective Java):考虑以下哈希码实现
这是一个有效的实现,但它也是最糟糕的实现 . 了解原因 .
A和B是两个独立的对象,由于
String
的hashCode()
的实现,它们生成相同的哈希码 .==
只检查左侧和右侧是否共享相同的参考 . 它不会调用Object
的equals()
方法 .所以,不,哈希和对象引用不是一回事 .