Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java equals()方法的工作原理_Java_Equals - Fatal编程技术网

Java equals()方法的工作原理

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("

我正在深入研究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语言等于方法

  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编程语言不需要这种实现技术。)