为自定义类实现哈希码和等于

Q L*_*Liu 7 java equals hashcode abstract-data-type custom-object

所以我有很多自定义类,它们内部也有使用组合的自定义类。

我的自定义类具有经常更改的变量,我将它们添加到 HashSets。所以我的问题是当我实现 hashCode 时 - 我应该为一个只有私有字段不断变化的类做什么?

这是一个自定义类的示例:

public class Cell {
    protected boolean isActive;
    protected boolean wasActive;

    public Cell() {
    this.isActive = false;
    this.wasActive = false;
    }

    // getter and setter methods...

    @Override
    public int hashCode() {
    // HOW SHOULD I IMPLEMENT THIS IF THIS custom object is constantly
        // being added into HashSets and have it's private fields isActive
        // and wasActive constantly changed.
    }

    // ANOTHER QUESTION Am I missing anything with this below equals implementation?
    @Override
    public boolean equals(Object object) {
    boolean result = false;
    if (object instanceof Cell) {
        Cell otherCell = (Cell) object;
        result = (this.isActive == otherCell.isActive && this.wasActive == 
            otherCell.wasActive);
    }
    return result;
    }
Run Code Online (Sandbox Code Playgroud)

Ank*_*thi 6

Java 中的 Equals 和 hashCode 契约:

当我们重写 equals() 方法时,我们必须重写 hashCode(),Java 中的 equals 方法必须遵循与 Java 中的 hashCode 方法的约定,如下所述。

  1. 如果两个对象通过 equals() 方法相等,则哈希码必须相同。
  2. 如果两个对象通过 equals() 方法不相等,则哈希码可能相同或不同。

这些是类的 equals 和 hashcode 方法的示例实现:

 //Hashcode Implementation    

   @Override
    public int hashCode() 
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + (isActive ? 1231 : 1237);
        result = prime * result + (wasActive ? 1231 : 1237);
        return result;
    }

//equals Implementation    
    @Override
    public boolean equals(Object obj) 
    {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Cell other = (Cell) obj;
        if (isActive != other.isActive)
            return false;
        if (wasActive != other.wasActive)
            return false;
        return true;
    }
Run Code Online (Sandbox Code Playgroud)

  • 你认为这会有什么帮助?我的意思是你在哈希码中使用可变字段。现在,如果 Cell 对象用作散列集合中的键,并且在 HashMap 中输入时两个字段都为真,那么现在字段会发生变化,哈希码也会发生变化!如果您现在尝试基于该对象查找某些内容,则 HashMap 将在其他存储桶中查找而不是在原始存储桶中查找,并且您将找不到该对象。 (2认同)

Vee*_*era 1

这是具有私有字段的类的示例。

public class Test {

    private int num;
    private String data;

    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if ((obj == null) || (obj.getClass() != this.getClass()))
            return false;
        // object must be Test at this point
        Test test = (Test) obj;
        return num == test.num
                && (data == test.data || (data != null && data
                        .equals(test.data)));
    }

    public int hashCode() {
        int hash = 7;
        hash = 31 * hash + num;
        hash = 31 * hash + (null == data ? 0 : data.hashCode());
        return hash;
    }

}
Run Code Online (Sandbox Code Playgroud)