2016-12-05 26 views
1
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)); 
} 

} 

輸出插入後存在: -HashMap的 - 以前的主要新相等的對象

Employee2 
Employee3 
true 
true 
Employee2 

這裏EMP1和EMP2是相等的對象。前2個輸出表示我們在hashmap中有2個入口(不是3個)。當我們在hashmap中插入第二個對象(emp2)時,它將刪除先前的條目,即emp1。但是第三個輸出表示hashmap仍然包含關鍵字emp1和第五個輸出,說明關鍵字emp1和emp2指向hashmap中的相同條目。我對hashmap的這種行爲感到困惑,即條目已經消失,但是鍵仍然存在,並指向下一個相等的對象。

+0

提示您的emp1和emp2都有相同的ID(10)! – Sikorski

+0

對於一個新手來說很好的輸入... – GhostCat

回答

0

由於兩個emp1emp2具有相同id即10,apache commons lib是將它們視爲equalhashcode也是相同的。因此,當你將emp2放入hashmap中時,它實際上不會爲hashmap添加新的鍵,它只是將現有的「Employee1」值替換爲「Employee2」。由於emp1和emp2是相同的,因此在hashmap上調用方法時,您將對這兩個對象都成立。 爲了避免這種情況:

  1. 分配不同的ID給您的員工
  2. 員工類
  3. 添加更多特性讓Java本身決定的哈希碼,等於,而不是使用Apache的共享庫。

我還可以補充一點,不要依賴HashCodeBuilder和EqualsBuilder的反射用法,而應該使用它們提供的顯式流暢API。

0
  1. 基本上,HashMap中使用key.hashCode()和key.equals()來定位的值,因此,如果兩個對象的hashCode()方法返回相同的值,和equals()也是真實的,那麼它們將考慮同樣的關鍵。
  2. commons lang的reflectionHashCode()和reflectionEquals()基於對象的字段來生成HashCode和Equals結果。在你的情況中,由於emp1和emp2只有一個字段ID,並且它們具有相同的值10,所以如果比較emp1和emp2,relfectionHashCode()將返回相同的值,而reflectionEquals()將返回true。

基於以上兩點,EMP1和EMP2實際上是HashMap中的觀點相同的密鑰。因此,emp.get(emp1)和emp.get(emp2)將返回相同的值,即「Employee2」。