2017-03-29 55 views
1

我有我的Emp類重載equals方法和putVal方法在HashMap中

class Emp 
{ 
    String empId; 
    public boolean equals(Emp e){..} 
    public boolean equals(Object o){..} 
    public int hashCode(){ 
    return empId.hashCode(); 
} 
} 

現在,如果我試圖添加的Emp對象的HashSet<Emp>兩種方法。

如果我看一下HashMap的putVal方法的代碼,該方法用於比較和設置值。代碼永遠不會將您傳遞的對象轉換爲java.lang.Object。因此每次調用equals(Emp)版本時都會如此。

但每次調用equals(Object o)。我想知道什麼時候將此Emp轉換爲java.lang.Object,以便每調用一次equals(Object o)

下面是putval片段我使用:

final V putVal(int hash, K key, V value, boolean onlyIfAbsent, 
         boolean evict) { 
    Node<K,V>[] tab; Node<K,V> p; int n, i; 
    if ((tab = table) == null || (n = tab.length) == 0) 
    n = (tab = resize()).length; 
    if ((p = tab[i = (n - 1) & hash]) == null) 
    tab[i] = newNode(hash, key, value, null); 
    else { 
    Node<K,V> e; K k; 
    if (p.hash == hash && 
      ((k = p.key) == key || (key != null && key.equals(k)))) 
     e = p; 
    else if (p instanceof TreeNode) 
     e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); 
        .... 
    } 
+0

在這裏推薦的另一件事:最好總是使用花括號來處理then/else語句;即使它只是一個單一的陳述。並且:精確地說明格式/縮進;因爲這有助於閱讀/理解代碼! – GhostCat

回答

3

編譯器擦除泛型類型參數,所以KV成爲Object當代碼被編譯。因此key.equals(k)執行equals(Object o)

+0

再次感謝伊蘭。 :) – ankit

2

超出了伊蘭的正確論據;點是不要做那。

不要過載public boolean equals(Object)

這是一種在Java中具有非常明確且清晰且已知的合同的方法。添加您自己的公共equals(Emp)只有增加您創建錯誤的風險。

如果有的話,使該方法是私人的;並從equals(Object)方法中調用它。

你看,超載是應該真正謹慎使用,因爲所有這一切發生在編譯時間觀念;特別是將它與多態性結合在一起時,可能會在運行時發生意想不到的事情(正如您剛剛學到的)。

+0

感謝GhostCat。點注意。 – ankit