HashMap - 插入新的相等对象后存在以前的Key

时间:2016-12-05 05:22:24

标签: java collections

import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

class Employee{
int id;

Employee(int id){
    this.id = id;
}
public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

@Override
public int hashCode(){      
    return HashCodeBuilder.reflectionHashCode(this);
}

@Override
public boolean equals(Object obj){      
    return EqualsBuilder.reflectionEquals(this, obj);   
}
}
public class P2 {

public static void main(String[] args) {
    Employee emp1 = new Employee(10);
    Employee emp2 = new Employee(10);
    Employee emp3 = new Employee(14);        
    HashMap<Employee,String> emp = new HashMap();
    emp.put(emp1, "Employee1");
    emp.put(emp2, "Employee2");
    emp.put(emp3, "Employee3");     
    Set set = emp.keySet();
    Iterator it = set.iterator();
    while(it.hasNext()){
        Employee empl = (Employee)it.next();
        System.out.println(emp.get(empl));
    }
    System.out.println(emp.containsKey(emp1));      
    System.out.println(emp1.equals(emp2));
    System.out.println(emp.get(emp1));
}

}

输出: -

Employee2
Employee3
true
true
Employee2

这里emp1和emp2是相等的对象。第2个输出表示我们在hashmap中有2个条目(不是3个)。我们在hashmap中插入第二个对象(emp2)的时刻它删除了前一个条目,即emp1。但是第三个输出表示hashmap仍然包含键emp1和第五个输出,表示键emp1和emp2指的是hashmap中的相同条目。我对hashmap的这种行为感到困惑,即条目已经消失,但是密钥仍然存在并引用下一个相等的对象。

1 个答案:

答案 0 :(得分:0)

  1. 基本上,HashMap使用key.hashCode()和key.equals()来定位值,所以如果两个对象hashCode()方法返回相同的值,而equals()也是true,那么他们会考虑相同的键。
  2. commons lang的reflectionHashCode()和reflectionEquals()基于对象的字段来生成HashCode和Equals结果。在你的情况下,因为emp1和emp2只有一个字段id,它们具有相同的值10,所以relfectionHashCode()将返回相同的值,如果比较emp1和emp2,reflectionEquals()将返回true。
  3. 基于以上两点,emp1和emp2实际上是HashMap视角中的相同键。因此emp.get(emp1)和emp.get(emp2)将返回相同的值,即&#34; Employee2&#34;。