创建hashCode()方法-Java

创建hashCode()方法-Java,java,hash,hashcode,Java,Hash,Hashcode,为我创建的类编写hashCode()方法时遇到一些问题。该类用于树集内部,因此,它实现了Comparable。该类具有以下变量: public class Node implements Comparable<Node> { Matrix matrix; int[] coordinates= new int[2]; Node father; int depth; int cost; 我还实现了一个equals()方法 public boolean eq

为我创建的类编写
hashCode()
方法时遇到一些问题。该类用于树集内部,因此,它实现了Comparable。该类具有以下变量:

public class Node implements Comparable<Node> {
   Matrix matrix;
   int[] coordinates= new int[2];
   Node father;
   int depth;
   int cost;
我还实现了一个
equals()
方法

public boolean equals(Object objectToCompare) {
    if(objectToCompare== this) {return true;}
    if(objectToCompare== null || objectToCompare.getClass()!= this.getClass()) {return false;}

    Node objectNode= (Node) objectToCompare;
    return this.father.equals(objectNode.father) &&
            this.depth== objectNode.depth &&
            this.cost== objectNode.cost &&
            this.matrix.equals(objectNode.matrix) &&
            Arrays.equals(this.coordinates, objectNode.coordinates);
}
说到这里,我有几个问题:

  • 既然我实现了一个新的
    equals()
    方法,我应该实现一个新的
    hashCode()
    方法吗
  • 如何使用这些变量实现新的hashCode
    method()
    ?(注意,类型矩阵的变量矩阵实现了一个
    hashCode()
    方法)

  • 就这些

    Intellij IDEA可以通过“右键单击”功能实现这一点。只要看到它正确地完成,你就会学到很多


    在任何情况下,您都应该重写这两种方法。

    您的
    compareTo
    方法与
    equals
    方法不一致:您的
    compareTo
    方法表示,如果两个实例具有相同的
    成本
    ,则两个实例是等效的,因此
    树集
    最多只能包含一个给定值的实例
    成本
    -但是你的
    等于
    方法说,只有当它们具有相同的
    成本
    并且在其他方面相同时,它们才是等价的

    因此,假设您的
    等于
    方法是正确的:

    • 您需要将
      比较修正为与之一致的
      方法
    • 您需要创建一个与之一致的
      hashCode
      方法。我建议使用与所使用的相同类型的逻辑,这是一种以特定顺序组装组件对象的哈希代码的简单而有效的方法;基本上,您可以编写如下内容:int hashCode=1; int hashCode = 1; hashCode = 31 * hashCode + (father == null ? 0 : father.hashCode()); hashCode = 31 * hashCode + depth; hashCode = 31 * hashCode + cost; hashCode = 31 * hashCode + matrix.hashCode(); hashCode = 31 * hashCode + java.util.Arrays.hashCode(coordinates); return hashCode; hashCode=31*hashCode+(父==null?0:father.hashCode()); hashCode=31*hashCode+深度; hashCode=31*hashCode+成本; hashCode=31*hashCode+matrix.hashCode(); hashCode=31*hashCode+java.util.Arrays.hashCode(坐标); 返回哈希码
    hashCode方法的契约规定,如果两个对象相等,则调用hashCode()应得到相同的整数结果。相反的情况不一定是真的,也就是说,如果两个哈希代码相同,则对象不必彼此相等

    查看equals方法(顺便说一句,它需要变量转换),您可以添加需要等于的所有内部成员变量的hashcode,使equals方法为true。e、 g

    public int hashCode() {
        return this.matrix.hashCode() + 
               this.coordinates[0] + 
               this.coordinates[1] + 
               this.father.hashCode() +
               this.depth + this.cost;               
    }
    
    上面假设矩阵和父矩阵从来都不是空值,如果不是这种情况,您需要确保检查空值

    如果您觉得更具冒险精神,可以将上面的几项乘以一个素数,以确保不同数据不会发生哈希代码冲突(如果您在哈希表和哈希映射中使用类,这将有助于提高性能)。如果您需要考虑空值,可以像这样更好地编写上述方法:

    public int hashCode() {
        return ((this.matrix == null) ? 0 : this.matrix.hashCode()) + 
               17 * this.coordinates[0] + 
               this.coordinates[1] + 
               ((this.father == null) ? 0 : this.father.hashCode()) +
               31 * this.depth + 19 * this.cost;               
    }
    

    如果集合很小,则可以从hashCode方法返回常量。它用于快速查找。hashcode类似于保存元素的框。规则是:

  • 相等的元素必须在同一个框中(具有相同的哈希代码)-当然
  • 不相等的元素可以在相同的框中,也可以在不同的框中
  • 然后返回常量,遵守这两条规则,但这会显著降低不小列表的性能(因为JVM将在所有元素中查找,而不是仅在同一框中的元素中查找)。但返回常数是一种糟糕的方法

    PS:对不起,我写了。英语不是我的母语


    PPS:通常您必须以与equals相同的方式实现hashCode方法(使用相同的元素)

    但如果我更改compareTo方法,这不会改变树集合中的组织方式吗?@Gonçalourenço:是的。这是我的观点;现在,如果
    n1.cost==n2.cost
    ,则包含
    n1
    TreeSet
    不能包含
    n2
    。这真的是你想要的吗?绝对不是。我想我得用别的东西来代替树集。既然你是第一个回答我问题的人,我就认为你的答案是正确的。谢谢你的帮助!只是不同意,如果两个hashcode相等,那么对象就不可能相等,树集同时包含这两个。我已经做到了,并且根据我的理解,我需要实现这三件事,以便它能够正确地处理这个节点结构。不过,我可能错了。请注意,
    father
    属于
    Node
    类型,因此如果它从来都不是
    null
    ,那么您的方法将导致无限递归和堆栈溢出。是的,我很担心。我想我得改变一下。谢谢你回答我的问题!因此,我们需要假设a)父路径可以为空,或者b)图中没有循环路径。如果以上两条都不正确,那么我们应该将父亲排除在hashCode计算之外。。。equals()方法对于父对象具有完全相同的(递归)问题。如果一个不同的父亲构成了一个不同的节点,如果其他节点的数据是相同的,那么你需要认真考虑,HM,这是一个很好的观点。我会记住这一点,它可能是我正在寻找的游戏规则改变者。@ToKra在我的例子中,它添加了这一行
    result=prime*result+getOuterType().hashCode(),但我只希望字段具有一致的hashcode(在重新加载应用程序之间),因此,通过注释该行,它可以正常工作。这是一个内部类tho,这就是为什么那条线出现的原因。
    
    public int hashCode() {
        return ((this.matrix == null) ? 0 : this.matrix.hashCode()) + 
               17 * this.coordinates[0] + 
               this.coordinates[1] + 
               ((this.father == null) ? 0 : this.father.hashCode()) +
               31 * this.depth + 19 * this.cost;               
    }