Java 为什么'==';即使hashcode值相同,仍返回false

Java 为什么'==';即使hashcode值相同,仍返回false,java,object,hash,reference,hashcode,Java,Object,Hash,Reference,Hashcode,我写了一本像这样的书 public class HashCodeImpl{ public int hashCode(){ return 1; } public static void main(String[] args) { // TODO Auto-generated method stub HashCodeUtil h= new HashCodeUtil(); HashCodeUtil h1=

我写了一本像这样的书

public class HashCodeImpl{
    public int hashCode(){
        return 1;
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        HashCodeUtil h=  new HashCodeUtil();
        HashCodeUtil h1=  new HashCodeUtil();
        System.out.println(h.hashCode());
        System.out.println(h1.hashCode());
        System.out.println(h);
        System.out.println(h1);
        System.out.println(h==h1);
    }
}
输出:

1 
com.manu.test.HashCodeUtil@1  
com.manu.test.HashCodeUtil@1 false
我的问题是:当我的hashCode方法返回相同的值时,为什么
System.out.println(h==h1)
这是假的吗


请解释。

因为它们是两个不同的对象引用<代码>=
比较引用,而不是
hashCode
结果

要获得所需的结果,可以重写类中的
equals
方法,并使用
h1.equals(h2)
查看它们是否相等。在这里,您可以使用
hashCode
的结果来简化对被比较对象相等性的评估(这并不意味着具有相同hashCode的两个对象相等)


但是请注意,即使对象具有相同的
hashCode
,并且根据
equals
方法的定义是等价的,它们也是不同的引用,在堆中占据不同的位置。

正如@ZouZou指出的那样,
hashCode
相等并不等同于对象相等。话虽如此,您甚至没有比较对象相等性。将两个对象与
=
进行比较是一种引用相等性检查,除非您确实知道自己在做什么,否则几乎不应该使用该检查。

您误解了
hashCode
的目的。正如其他人所指出的,
=
比较引用,而不是哈希代码。但是,一个比较值而不是引用的重写
equals
方法仍然不会比较哈希代码

想想看。。。哈希代码是一个
int
,因此哈希代码只有232个可能的值。但是有多少个可能的
String
s?很多很多超过232个。(因为每个
char
有216个可能值,有248个长度为3的
String
s可能值,并且随着
String
s的变长,这个数字一直在增长。)因此,如果两个
String
s的散列码相等,则不可能建立一个方案,其中两个
String
s总是相等的。大多数其他对象也是如此(尽管可能值数量相对较少的类可以为每个值设置唯一的哈希代码)


hashCode
的目的是找出一个可用于
hashMap
hashSet
的数字。为了提高映射或集合的效率,我们经常尝试使用一个函数来减少不相等对象具有不相等散列码的可能性。当然,对于大多数对象来说,这是不可能保证的。

您从哪里读到,如果两个哈希代码相同,那么引用必须相同
a.equals(b)=>a.hashCode()==b.hashCode()
,这是您唯一能知道的事情(没有提到您必须正确地重新定义equals和hashCode)。使用.equals,==是引用相等相关:-注意答案中对有效Java的引用,这是必须阅读的。“…因为
new
关键字”这将使用构造函数创建一个新的对象实例“.Ummm…”比较两个
String
s和
=
几乎是你永远不应该做的事情。(实际上,我说的是决不,句号。)但是我不认为你可以对一般的对象说同样的话。有些对象表示值,在这种情况下,应该有一个
equals
方法,你应该使用它而不是
=
。但不是所有的对象都是值对象,我认为这对其他对象不适用。我没有说从不,我说几乎从不.此外,如果您编写了一个正确的.equals方法,那么它的第一个检查应该是引用相等。