Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.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_Hashmap - Fatal编程技术网

有没有一种方法可以在Java中手动重新创建映射?

有没有一种方法可以在Java中手动重新创建映射?,java,hashmap,Java,Hashmap,我有一个具有两个属性的类Employee public class Employee { private int empId; private String empName; public int getEmpId() { return empId; } public void setEmpId(int empId) { this.empId = empId; } public String getE

我有一个具有两个属性的类
Employee

public class Employee {

    private int empId;
    private String 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 boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee employee = (Employee) o;
        return getEmpId() == employee.getEmpId() &&
                Objects.equals(getEmpName(), employee.getEmpName());
        //return Objects.equals(getEmpName(), employee.getEmpName());
    }

    @Override
    public int hashCode() {
        //return Objects.hash(getEmpId());
        return Objects.hash(getEmpId(), getEmpName());
    }
}
我使用这个类作为Hashmap中的键

现在,当我修改原始对象
emp
时(在本例中为员工对象更改名称),我无法访问最初保存在map中的条目。只有当我将名称回滚到其原始值时,我才能再次访问该对象

这表明,当我在Employee对象中更改名称时,它的哈希值已经更改,并且没有存储在Hashmap中正确的bucket下

Map Map=newhashmap();;
//设置名为Shashi的员工
员工emp=新员工();
emp.setEmpId(1);
emp.setEmpName(“沙石”);
//添加到地图
map.put(emp,emp.getEmpName());
//修改原始员工对象的名称
emp.setEmpName(“沙石布山”);
//此对象现在不作为地图中的键存在
Assert.assertFalse(map.containsKey(emp));
//创建同名对象(创建时使用)
Employee similarEmployee=新员工();
类似的employee.setEmpId(1);
similarEmployee.setEmpName(“Shashi”);
//Hashcode检查将通过,equals将失败
Assert.assertFalse(map.containsKey(similarEmployee));
Assert.assertNull(map.get(similarEmployee));
//创建具有相同名称(修改名称)的对象
员工另一个相似的员工=新员工();
另一个类似的雇员。setEmpId(1);
另一名类似员工。setEmpName(“沙石布山”);
//哈希代码检查将失败
Assert.assertFalse(map.containsKey(另一个类似的雇员));
Assert.assertNull(map.get(另一个类似的雇员));
//现在,如果我回滚名称,我也可以使用新创建的对象再次获取。
//从现在起,这个新对象将等同于旧对象。
emp.setEmpName(“沙石”);
Assert.assertTrue(map.containsKey(similarEmployee));
Assert.assertNotNull(map.get(similarEmployee));
能够在map中获取对象的问题的一个解决方案是使Employee类不可变

我可以想到的另一个理论解决方案是重新灰化映射,并将修改后的employee对象保留在映射的正确存储桶中,但我在hashmap中看不到任何重新灰化它的方法。请建议我的思路是否正确,或者是否有其他解决方案


另外,所有这些都是为了理解hashmap,所以对于如何解决这个问题没有限制

我认为empId可以唯一地识别员工

所以
equals
hashCode
方法只需要处理empId字段:

   @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee employee = (Employee) o;
        return getEmpId() == employee.getEmpId());
    }

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

这就是为什么您不应该在基于哈希的结构中使用可变对象作为键的原因。对于哈希映射键,我认为您只有2个选项:1)使其不可变,2)不重写哈希代码和等于,并使用原始对象实例lookups@boot-邦尼的回答正是我想说的。如果您确实想更改密钥,唯一安全的方法是从hashmap中删除密钥,更改密钥,然后将其放回。因此,如果我不重写equals和hashcode,则Employee的每个新实例都将不同,无论其id和名称是否相同。到目前为止,在方法中只使用id的建议(完全忽略名称)对我来说似乎是有效的或者只使用整数id作为映射键
   @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee employee = (Employee) o;
        return getEmpId() == employee.getEmpId());
    }

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