Java 正在将重复的自定义对象添加到Hashset

Java 正在将重复的自定义对象添加到Hashset,java,hashset,hashcode,Java,Hashset,Hashcode,我有一个Employee类,它有两个属性id和name。我正在重写hashcode和equals方法,如下所示 Employee.java: import java.util.Objects; public class Employee { private int id; private String name; public int getId() { return id; } public void setId(int id)

我有一个Employee类,它有两个属性id和name。我正在重写hashcode和equals方法,如下所示

Employee.java:

import java.util.Objects;

public class Employee {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + "]";
    }
}
现在我有了一个测试类,我在其中创建了一个名为“Chris Gayle”的employee类对象,并将其添加到HashSet中。之后,我将这个现有employee对象的名称修改为“Kieron Pollard”,并将这个修改后的employee对象再次添加到hashset中

TestSet.java

import java.util.HashSet;
import java.util.Set;

public class TestSet {

 public static void main(String[] args) {
     Set<Employee> hashSet = new HashSet<Employee>();

     Employee emp1 = new Employee();
     emp1.setId(1);
     emp1.setName("Chris Gayle");

     hashSet.add(emp1);

     System.out.println(hashSet);

     emp1.setName("Kieron Pollard");
     hashSet.add(emp1);
     System.out.println(hashSet.size());
     System.out.println(hashSet);
}

}

因为,set不允许重复的元素,但是在上面的场景中,我们在输出中得到了重复的元素。那么,处理这种行为的正确方法是什么呢。

你在这里射中了自己的脚

@Override
public int hashCode() {
    return Objects.hash(id, name);
}
如果
hashCode
是由
id
name
定义的&在再次将对象添加到
HashSet
之前更改名称,显然会得到重复的条目。提醒:对象的唯一性由
hashCode
-确定,这就是
HashSet
用来确定对象是否已经在
集中的方法

你的唯一性标准是什么?如果
id
是唯一的,请在
hashCode
中仅使用
id

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

谢谢你提起这件事。您应该看看
哈希集是如何实现的。您的示例还提供了一个关于为什么首选不变性的好主意

下面是正在发生的事情

  • 您创建了一个对象,并将其添加到
    哈希集中
    
  • HashSet
    使用对象的哈希存储对对象的引用。假设hash是10(对于id=1,name=chrisgayle)
  • 现在,当您更改对象时,
    HashSet
    不知道您对该对象所做的更改。它只保存引用,但更改了对象的哈希。让我们说20(id=1,name=Kieron Pollard)
  • equals和dashcode之间有一种关系。如果对象的散列码相等,则对象可以相等。散列码是不同的,那么对象将永远不相等。因此,根据这种逻辑,HashSet在您添加相同对象或第二次添加相同对象时添加了一个新条目

如果您尝试使用
newhashset(HashSet)
创建一个新的HashSet,那么您将只看到一个对象。

为什么要使用标记?您的问题与Java Enterprise Edition server客户端交互选项有什么直接关系?我已经回答了您的问题并更新了标记。请小心使用标签,因为标签和问题标题是问题中最重要的部分,有助于吸引正确的专家对其进行审查的标签是相同的。这里的实现是关于散列的,所以我解释了散列中的关系。
@Override
public int hashCode() {
    return Objects.hash(id);
}