Java 我应该如何重写equals和hashcode方法以避免向HashSet添加相等的对象?

Java 我应该如何重写equals和hashcode方法以避免向HashSet添加相等的对象?,java,Java,我研究过类似的示例,并像这样覆盖了这些方法,但仍然使用相同的名称但不同的id添加到HashSet对象中 public class NamedObject { String name; BigInteger id; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null

我研究过类似的示例,并像这样覆盖了这些方法,但仍然使用相同的名称但不同的id添加到
HashSet
对象中

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
对象中

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
,在相等性检查中只使用
name
HashSet
仅在找到与您尝试添加的对象具有相同哈希代码的现有对象时才会调用
equals()
。。。如果您的ID不同,则散列码不太可能不同,因此它从不使用同名对象调用
equals

您的
hashCode()
equals()
方法必须彼此一致。您需要确定相等是基于名称、ID还是基于两者-然后在
hashCode()
equals()
中都使用它

从文件中:

hashCode的总合同为:

  • 在Java应用程序的执行过程中,每当在同一对象上多次调用它时,
    hashCode
    方法必须一致地返回相同的整数,前提是不修改对象上的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致
  • 如果根据
    equals(Object)
    方法,两个对象相等,那么对两个对象中的每一个调用
    hashCode
    方法必须产生相同的整数结果
  • 根据
    equals(java.lang.Object)
    方法,如果两个对象不相等,则对两个对象中的每一个调用
    hashCode
    方法都必须产生不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能
目前,您的方法打破了这些需求的中间部分

我研究过类似的示例,并像这样覆盖了这些方法,但仍然使用相同的名称但不同的id添加到
HashSet
对象中

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
,在相等性检查中只使用
name
HashSet
仅在找到与您尝试添加的对象具有相同哈希代码的现有对象时才会调用
equals()
。。。如果您的ID不同,则散列码不太可能不同,因此它从不使用同名对象调用
equals

您的
hashCode()
equals()
方法必须彼此一致。您需要确定相等是基于名称、ID还是基于两者-然后在
hashCode()
equals()
中都使用它

从文件中:

hashCode的总合同为:

  • 在Java应用程序的执行过程中,每当在同一对象上多次调用它时,
    hashCode
    方法必须一致地返回相同的整数,前提是不修改对象上的equals比较中使用的信息。从应用程序的一次执行到同一应用程序的另一次执行,该整数不必保持一致
  • 如果根据
    equals(Object)
    方法,两个对象相等,那么对两个对象中的每一个调用
    hashCode
    方法必须产生相同的整数结果
  • 根据
    equals(java.lang.Object)
    方法,如果两个对象不相等,则对两个对象中的每一个调用
    hashCode
    方法都必须产生不同的整数结果。但是,程序员应该知道,为不相等的对象生成不同的整数结果可能会提高哈希表的性能

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

您确定这是您需要的正确的
equals
方法吗?您想做什么,为什么这样做?我假设两个对象是相等的,如果它们的名称相同。或者你说的是检查参数实例?我试图避免添加相等的对象,我检查参数类和名称。你确定这是你需要的正确的
equals
方法吗?你想做什么,为什么这样做?我假设两个对象是相等的,如果它们有相等的名称。或者你说的是检查参数实例?我试图避免添加相等的对象,我检查参数类和名称。这是我的错误,我没有正确地提问。我想要一个具有唯一名称的对象的哈希集。因此,在检查等价性时,我只检查名称。但我仍然以相同的名称被添加到我的set对象中。@will\u-hunting:但你的代码没有这样做。它对哈希代码使用
id
,而不是
name
。要修复它,您只需更改
hashCode()
以返回
name.hashCode()
。这是我的错误,我没有正确地提问。我想要一个具有唯一名称的对象的哈希集。因此,在检查等价性时,我只检查名称。但我仍然以相同的名称被添加到我的set对象中。@will\u-hunting:但你的代码没有这样做。它对哈希代码使用
id
,而不是
name
。要修复它,只需更改
hashCode()
以返回
name.hashCode()