我研究了类似的示例,并像这样重写了这些方法,但仍然将它们添加到具有相同名称但又具有不同id的HashSet<NamedObject>对象中。

public class NamedObject {
    String name;
    BigInteger id;

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

        NamedObject that = (NamedObject) o;
        return this.name.equals(that.getName());
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }
}

最佳答案

我研究了类似的示例,并像这样重写了这些方法,但仍然将它们添加到具有相同名称但又具有不同id的HashSet<NamedObject>对象中。


是的,因为您仅在哈希码中使用id,并且在相等性检查中仅使用nameHashSet<>仅在找到具有与您要添加的哈希码相同的哈希码的现有对象时才会调用equals() ...如果您的ID不同,则哈希码不同的可能性很小,因此它永远不会使用具有相同名称的对象调用equals

您的hashCode()equals()方法必须彼此一致。您需要确定是否基于名称,ID或同时基于两者-然后在hashCode()equals()中使用它们。

Object.hashCode()文档中:


  hashCode的一般约定为:
  
  
  在Java应用程序执行期间,只要在同一对象上多次调用它,hashCode方法必须一致地返回相同的整数,前提是未修改该对象的equals比较中使用的信息。从一个应用程序的一次执行到同一应用程序的另一次执行,此整数不必保持一致。
  如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
  如果根据equals(java.lang.Object)方法,两个对象不相等,则不需要在两个对象中的每一个上调用hashCode方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。
  


您的方法目前打破了这些要求的中间部分。

09-10 08:33
查看更多