【问题标题】:why Hashset remove duplicate object not work为什么Hashset删除重复对象不起作用
【发布时间】:2021-03-05 01:24:04
【问题描述】:

我想用set来删除重复的对象,UserEntity是这样的:

public class UserEntity {
    String name;
    int age;
    @Override
    public String toString() {
        return "UserEntity [name=" + name + ", age=" + age + "]";
    }
    public UserEntity(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public boolean equals(Object o1) {
        UserEntity user=(UserEntity) o1;
        return this.age==user.age && user.name.equals(this.name);
    }
    
}

然后我创建了一个集合来添加两个名为 alex 的用户,他们的年龄是 20 岁,但是集合中有两个用户:

UserEntity user1 = new UserEntity("alex", 20);
UserEntity user2 = new UserEntity("alex", 20);
System.out.println(user1.equals(user2));
Set<UserEntity> set=new HashSet<>();
set.add(user1);
set.add(user2);
System.out.println(set.size());

结果是:

true
2

为什么集合不删除重复的对象?

【问题讨论】:

  • 您还需要覆盖Object#hashCode

标签: java set


【解决方案1】:

broke the contract,不覆盖hashCode()

hashCode的通用合约是:

  • 每当在同一对象上多次调用它时 执行 Java 应用程序时,hashCode 方法必须一致 返回相同的整数,只要不使用 equals 中的信息 对象上的比较被修改。这个整数不需要保留 从应用程序的一次执行到另一次执行一致 相同的应用程序。

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

  • 不是必须的 如果两个对象根据 equals(java.lang.Object) 方法,然后调用 hashCode 方法 这两个对象中的每一个都必须产生不同的整数结果。 然而,程序员应该意识到产生不同的 不相等对象的整数结果可以提高 哈希表。


来自equals():

注意,一般需要重写hashCode方法 每当此方法被覆盖时,以保持一般 hashCode 方法的契约,它规定相等的对象必须 具有相同的哈希码。


由于您违反了规则,HashSet 不能保证它会正常工作。好像被背叛了一样。

shouldn't happen 是真实代码,因为你不应该在真实代码中违反合约

【讨论】:

    【解决方案2】:

    当你实例化一个新对象的时候,就是这样,一个新对象,即使它包含相同的数据,对象的hashCode仍然是不同的。您可能还想考虑覆盖Object#hashCode

    【讨论】:

      【解决方案3】:

      你错过了这个。添加到您的代码中,它将起作用。

      public int hashCode() {
              return this.name.hashCode();
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-09-22
        • 1970-01-01
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-14
        相关资源
        最近更新 更多