在可变对象作为键的情况下的hashmap迭代行为

时间:2018-01-25 13:36:06

标签: java

我创建了一个Employee类,并覆盖了hashCodeequals方法。现在我将此类用作HashMap创建中的关键字。在修改键之前一切正常,但是一旦我开始玩键并尝试查看HashMap内容,它的输出就会让我感到困惑。当我迭代HashMap时,它保留了在我之前的步骤中已经被我自己覆盖的键。所以e1,e2和e3是3个关键对象。我修改e1指向新的新对象(name = hrithik,id = 123),因此map.get方法返回null,这很好。现在我将e2(name = sachin,id = 456)分配给e1,因此e1的旧内容应该丢失(name = sachin,id = 123)。现在问题从这里开始。当我迭代hashmap时,我看到e1键内容仍指向旧引用(name = sachin,id = 123)而不是(name = sachin,id = 456)。它背后的原因是什么?

Employee上课

package hashmapConfusion;

public class Employee {

    public String getName() {
        return name;
    }

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

    public int getEmpId() {
        return empId;
    }

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

    private String name;
    private int empId;

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

    @Override
    public int hashCode() {
        return 31*(name.length())*(name.charAt(0));
    }

    @Override
    public boolean equals(Object o) {
        if(!(o instanceof Employee)) {
            return false;
        }else {
            Employee an = (Employee) o;
            if(this.name.equals(an.name) && this.empId==an.empId) {
                return true;
            }
        }
        return false;
    }
}

HashMap

的测试类
package hashmapConfusion;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class AddEmployeeHashMap {

    public static void main(String[] args) {

        Map<Employee, String> map = new HashMap<Employee, String>();
        Employee e1 = new Employee("sachin",123);
        Employee e2 = new Employee("sachin",456);
        Employee e3 = new Employee("sachin",456);
        map.put(e1, "lo");
        map.put(e2, "lo another");
        map.put(e3, "lo another another");
        /*map.put(e2, "value");
        map.put(e3, "value3");*/
        /*e3 = new Employee("sachin",456);*/
        System.out.println(map.get(e1));
        e1= new Employee("hrithik",123);
        System.out.println(map.get(e1));
        e1=e2;
        System.out.println("value 1"+map.get(e1));
        System.out.println("value 2"+map.get(e2));
        for(Map.Entry<Employee, String> obj:map.entrySet()) {
            System.out.println("AFTER ONE KEY CHANGE");
            System.out.println(obj.getKey()+"="+obj.getValue());
        }
        for(Employee obj:map.keySet()) {
            System.out.println("key values");
            System.out.println(obj.getName()+"="+obj.getEmpId());
        }
        e2.setEmpId(300);
        System.out.println("size after change both keys-"+map.size());
        for(Entry<Employee, String> obj:map.entrySet()) {
            System.out.println();
            System.out.println(obj.getKey()+"="+obj.getValue());
        }
        System.out.println(map.size());
        /*map.forEach((key, val)->{
            Employee e4 = new Employee("sachin",456);
            System.out.println(val+"-");
            if(key.equals(e4))
                System.out.println("found val-"+val);
        });*/

    }

}

输出

lo
null
value 1lo another another
value 2lo another another
AFTER ONE KEY CHANGE
//WHY DOES IT PRINT LO WHEN KEY HAS ALREADY BEEN CHANGED FROM E1 TO E2
hashmapConfusion.Employee@538e=lo
AFTER ONE KEY CHANGE
hashmapConfusion.Employee@538e=lo another another
key values
//WHY IT IS SPITTING THE OLD KEY VALUES WHICH ARE WAY BACK OVERRRIDDEN
sachin=123
key values
sachin=456
size after change both keys-2
hashmapConfusion.Employee@538e=lo
hashmapConfusion.Employee@538e=lo another another
2

0 个答案:

没有答案