Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/388.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 同一对象用作映射中两个条目的键_Java_Object_Hashmap - Fatal编程技术网

Java 同一对象用作映射中两个条目的键

Java 同一对象用作映射中两个条目的键,java,object,hashmap,Java,Object,Hashmap,我有一个雇员类别如下 class Employee { int empId; String empName; public Employee() { } Employee(int empId, String empName) { this.empId = empId; this.empName = empName; } public int getEmpId() { return empId; } public void setEmpId(int empId) {

我有一个雇员类别如下

class Employee {
int empId;
String empName;

public Employee() {
}

Employee(int empId, String empName) {
    this.empId = empId;
    this.empName = empName;
}

public int getEmpId() {
    return empId;
}

public void setEmpId(int empId) {
    this.empId = empId;
}

public String getEmpName() {
    return empName;
}

public void setEmpName(String empName) {
    this.empName = empName;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + empId;
    result = prime * result + ((empName == null) ? 0 : empName.hashCode());
    return result;
}

@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 (empId != other.empId)
        return false;
    if (empName == null) {
        if (other.empName != null)
            return false;
    } else if (!empName.equals(other.empName))
        return false;
    return true;
}}
    Map<Employee, String> empMap = new HashMap<>();
    Employee e1 = new Employee(123, "xyz");
    empMap.put(e1, "asd");
    System.out.println(empMap.size());
    System.out.println(empMap.get(e1));
    e1.setEmpId(122);
    empMap.put(e1, "asd");
    System.out.println(empMap.size());
    System.out.println(empMap.get(new Employee(122, "xyz")));
    System.out.println(empMap.get(new Employee(123, "xyz")));

    Set<Employee> mapEmpKeys = empMap.keySet();
    mapEmpKeys.forEach(emp -> {
        System.out.println("Employee ID: " + emp.getEmpId() + " Employee Name: " + emp.getEmpName());
    });
我使用这个Employee类对象作为HashMap中的键,如下所示

class Employee {
int empId;
String empName;

public Employee() {
}

Employee(int empId, String empName) {
    this.empId = empId;
    this.empName = empName;
}

public int getEmpId() {
    return empId;
}

public void setEmpId(int empId) {
    this.empId = empId;
}

public String getEmpName() {
    return empName;
}

public void setEmpName(String empName) {
    this.empName = empName;
}

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + empId;
    result = prime * result + ((empName == null) ? 0 : empName.hashCode());
    return result;
}

@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 (empId != other.empId)
        return false;
    if (empName == null) {
        if (other.empName != null)
            return false;
    } else if (!empName.equals(other.empName))
        return false;
    return true;
}}
    Map<Employee, String> empMap = new HashMap<>();
    Employee e1 = new Employee(123, "xyz");
    empMap.put(e1, "asd");
    System.out.println(empMap.size());
    System.out.println(empMap.get(e1));
    e1.setEmpId(122);
    empMap.put(e1, "asd");
    System.out.println(empMap.size());
    System.out.println(empMap.get(new Employee(122, "xyz")));
    System.out.println(empMap.get(new Employee(123, "xyz")));

    Set<Employee> mapEmpKeys = empMap.keySet();
    mapEmpKeys.forEach(emp -> {
        System.out.println("Employee ID: " + emp.getEmpId() + " Employee Name: " + emp.getEmpName());
    });
Map empMap=newhashmap();
员工e1=新员工(123,“xyz”);
empMap.put(e1,“asd”);
System.out.println(empMap.size());
System.out.println(empMap.get(e1));
e1.setEmpId(122);
empMap.put(e1,“asd”);
System.out.println(empMap.size());
System.out.println(empMap.get(新员工(122,“xyz”));
System.out.println(empMap.get(新员工(123,“xyz”));
Set mapEmpKeys=empMap.keySet();
mapEmpKeys.forEach(emp->{
System.out.println(“员工ID:+emp.getEmpId()+”员工姓名:+emp.getEmpName());
});
程序的输出:

1.
自闭症
2.
自闭症
无效的
员工ID:122员工姓名:xyz
员工ID:122员工姓名:xyz

我的问题是,即使作为关键点的对象是相同的,我得到的地图大小为2。有人能给我解释一下,通过将Employee对象e1的id设置为不同的值,并将其再次添加到map中,将其大小设置为2,当我在map的键集上迭代时,两个条目的对象都是相同的。钥匙在地图上必须是唯一的,对吗?那为什么我会得到相同的对象键两次呢?
谢谢

当您在
HashMap
中变异用作键的实例时,如果您修改用于确定相等性或计算
hashCode()
的属性,则会破坏
HashMap

第一次将密钥放入映射时,它被放入与基于值123和“xyz”计算的
hashCode()
相对应的bucket中

第二次在映射中放入同一个键时,它被放入另一个bucket中,该bucket与基于值122和“xyz”计算的
hashCode()
相对应


由于
HashMap
首先找到与密钥的
hashCode()
匹配的bucket,然后才检查该bucket中的所有密钥是否相等,因此如果给定密钥的
hashCode()
已更改,则对
put
的第二次调用将尝试在新bucket中找到它(匹配新的
hashCode()
),在那里找不到。因此,同一个密钥被添加两次。

简短回答-如果需要将其用作密钥,Employee应该是不可变的。在更改员工id之前和之后打印哈希代码。同时打印它们是否相等。只有一个
Employee
对象。仅仅因为您修改了它并将其存储在地图中,并不意味着现在有两个。而且,可变键是个坏主意。