Java equals()方法的工作原理
我正在深入研究Java的基础知识。 我由此推断,java equals方法意味着,如果两个对象相等,那么它们必须具有相同的hashCode() 这是我的例子Java equals()方法的工作原理,java,equals,Java,Equals,我正在深入研究Java的基础知识。 我由此推断,java equals方法意味着,如果两个对象相等,那么它们必须具有相同的hashCode() 这是我的例子 public class Equals { /** * @param args */ public static void main(String[] args) { String a = new String("a"); String b = new String("
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语言等于方法
public boolean equals(Object obj) {
return (this == obj);
}
在我上面的示例中,a.equals(b)返回true,这意味着满足条件a==b。但是为什么在那个例子中a==b返回false呢
哈希代码和地址不一样吗?
另外,当我们说a==b或其他什么的时候,hashCode会比较吗?不,hashCode和address不一样。 因为a==b没有比较哈希代码 是的,当我们说a==b时,会比较其他东西。 (这也不是地址,真的,但已经足够近了)
另外,仅仅因为“相等的对象具有相等的哈希代码”并不意味着“相等的哈希代码意味着相等的对象”。
String
类已经重写了equals()
方法。请按照文档进行操作
a、 equals(b)返回true,表示满足条件a==b
这是equals()
的默认实现,在Object
类中,String
类已覆盖默认实现。当且仅当参数不为null并且是表示与此对象相同的字符序列的字符串对象时,它才会返回true
哈希代码和地址不一样吗
不一定,为了进一步阅读。a.equals(b)与a==b不同
a、 equals(b)基于equals()实现检查两个对象是否相等
a==b检查两个对象是否具有相同的引用
如果a==b为true,则a.equals(b)必须为true,因为它们引用的是同一对象,而不是相反。String类覆盖对象类的equals()方法的默认实现。您提供的equals方法代码不是来自String类而是来自Object类,Object类被String类实现覆盖,后者检查两个对象的内容是否相同。Java中的
=
操作符比较对象引用,看它们是否引用同一对象。因为变量a
和b
引用不同的对象,所以根据=
它们并不相等
而hashCode
方法不会返回String
中的地址,因为该类具有
此外,该方法已在
String
中实现,以比较字符串的内容;这就是为什么a.equals(b)
在这里返回true
。由于String
实现了hashCode()
,a和b是两个独立的对象,它们生成相同的哈希代码<代码>=只需检查左右两侧是否共享相同的参考。它不调用对象的equals()
方法
因此,不,哈希和对象引用不是一回事。对象的哈希代码意味着被覆盖
对于字符串类,使用的公式如下:
s[0]*31^(n-1)+s[1]*31^(n-2)+…+s[n-1]
我鼓励你们搜索为什么31被用作乘数而不是其他数字
覆盖哈希代码的一般经验法则是,对于不同的对象,哈希代码应该尽可能不同
为了实现这一点,建议您在计算散列值时考虑对象的每个重要字段
注意:这只是一个无关的思想食粮(来源:effectivejava):
考虑hash码的以下实现
int hashcode(){
return 10;
}
这是一个有效的实现,但也是最糟糕的实现。了解原因
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
不要被散列码分心。这不是平等的决定因素。问问你自己,如果resut是一个整数,可以有多少个哈希码?现在可以有多少字符串?Hashcode!=地址。Hashcode值通常用作哈希表中的索引,但它也经常被重写以生成更好的哈希。这即使不是更糟,也是同样糟糕的。每次返回相同的值都违背了散列代码的目的。Java文档指出:“只要合理可行,类对象定义的散列代码方法确实会为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但JavaTM编程语言不需要这种实现技术。)