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