Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.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中hashCode与equals方法的关系_Java - Fatal编程技术网

Java中hashCode与equals方法的关系

Java中hashCode与equals方法的关系,java,Java,我在很多地方读到过这样的话,在Java中重写equals方法时,也应该重写hashCode方法,否则就是“违反合同” 但到目前为止,若我只重写equals方法,而不重写hashCode方法,那个么我并没有遇到任何问题 合同是什么?为什么我在违反合同时没有遇到任何问题?在这种情况下,如果我没有重写hashCode方法,我会面临一个问题吗?契约是:如果两个对象相等,那么它们应该具有相同的hashCode;如果两个对象不相等,那么它们可能具有或不具有相同的hashCode 尝试使用对象作为HashMa

我在很多地方读到过这样的话,在Java中重写
equals
方法时,也应该重写
hashCode
方法,否则就是“违反合同”

但到目前为止,若我只重写equals方法,而不重写hashCode方法,那个么我并没有遇到任何问题


合同是什么?为什么我在违反合同时没有遇到任何问题?在这种情况下,如果我没有重写hashCode方法,我会面临一个问题吗?

契约是:如果两个对象相等,那么它们应该具有相同的hashCode;如果两个对象不相等,那么它们可能具有或不具有相同的hashCode


尝试使用对象作为HashMap中的键(根据joachim sauer的评论编辑),您将开始面临麻烦。契约是一种指导原则,而不是强加给你的东西。

你将遇到的问题是,在集合中,元素的唯一性是根据
.equals()
.hashCode()
计算的,例如
HashMap
中的键

顾名思义,它依赖于哈希表,哈希桶是对象的
.hashCode()
的函数

如果有两个对象是
.equals()
,但具有不同的哈希代码,则会丢失

合同中重要的一部分是:属于
.equals()
的对象必须具有相同的
.hashCode()


这些都记录在。并且说你必须在家里做。说得够多了。

是的,它应该被覆盖。如果您认为需要重写
equals()
,则需要重写
hashCode()
,反之亦然。工程总承包合同为:

  • 在Java应用程序的执行过程中,每当在同一对象上多次调用hashCode方法时,只要没有修改对象上的equals比较中使用的信息,hashCode方法必须始终返回相同的整数。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致

  • 如果根据equals(Object)方法两个对象相等,则对两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。

  • 根据equals(java.lang.Object)方法,如果两个对象不相等,则对这两个对象中的每一个调用hashCode方法都必须产生不同的整数结果,这不是必需的。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能


  • 合同规定,如果
    obj1.equals(obj2)
    然后
    obj1.hashCode()==obj2.hashCode()
    ,这主要是出于性能原因,因为映射主要使用hashCode方法比较条目键。

    请参见

    信中说:

    如果根据
    equals(Object)
    方法,两个对象相等, 然后必须对两个对象中的每个对象调用
    hashCode
    方法 生成相同的整数结果

    (我强调)

    如果您只重写
    equals()
    而不重写
    hashCode()
    ,则您的类违反了此约定

    该方法的JavaDoc中也提到了这一点:

    请注意,通常需要重写
    hashCode
    方法 每当重写此方法时,以保持
    hashCode
    方法的契约,该方法声明必须有相等的对象 具有相等的散列码


    看看
    哈希表
    哈希映射
    哈希集
    等等。它们都将散列键存储为它们的键。调用
    get(objectkey)
    时,将生成参数的散列,并在给定的散列中查找


    如果不覆盖
    hashCode()
    并且密钥的实例已更改(例如,一个简单的字符串根本不重要),则
    hashCode()
    可能会导致同一对象有两个不同的hashCode,从而导致根据文档在
    map.get()
    中找不到给定的密钥,hashCode的默认实现将返回每个对象不同的整数

    只要合理可行,类对象定义的hashCode方法就可以 返回不同对象的不同整数。(这通常由 将对象的内部地址转换为整数,但此实现
    JavaTM编程语言不需要这种技术。)

    但是,有时您希望具有相同含义的不同对象的哈希代码相同。比如说

    Student s1 = new Student("John", 18);
    Student s2 = new Student("John", 18);
    s1.hashCode() != s2.hashCode(); // With the default implementation of hashCode
    

    如果在集合框架中使用哈希数据结构,例如哈希表、哈希集,就会出现这种问题特别是对于HashSet之类的集合,您最终将拥有重复的元素并违反集合约定。

    “应该有”=>“必须有”,并且您应该提到“尝试将它们用作HashMap中的键”。如果obj1!=obj2然后obj1.hasCode()!=obj2.hashCode()@fge你说得对,hashCodes可能会冲突,我想这个“契约”的问题是没有任何东西能强制它。如果你弄坏了它,没有什么东西会马上坏。但是,如果您不遵守合同中您的部分,处理对象的其他代码可以自由“中断”。当你试图在
    HashMap
    .Short和“Nuff说”中使用这样的对象时,就会发生这种情况+1@fge我有一个困惑,为什么在HashMap中重写hashCode方法时需要重写equals方法。在任何情况下,如果对象的hashcode相等,hashmap将替换该值。@VikasVerma不,它不相等;首先,计算密钥的散列码,然后查询正确的bucket是否相等。如果不重写.equals(),可能会遇到两个具有相同哈希代码的对象不相等的情况,因为