I created an Employee class and overridden the hashCode and equals methods. Now I use this class as key in HashMap creation. Until the keys are not modified everything works fine, but as soon as I start playing with keys and try to view the HashMap contents, its output confuses me. When I iterate the HashMap, it retains the key which was already overridden by myself in earlier steps. So e1, e2 and e3 are 3 key objects. i modify e1 to point to new fresh object(name=hrithik, id=123) and thus map.get method returns null which is fine. now i assign e2(name=sachin,id=456) to e1 and thus e1's old content should be lost(name=sachin,id=123). Now problem starts here. When i iterate the hashmap, i see the e1 key contents still pointing to old reference(name=sachin,id=123) instead of (name=sachin,id=456). What is the reason behind it?
Employee class
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;
    }
}
Test class for 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);
        });*/
    }
}
And the output
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
