2017-11-03 60 views
0

當談到Java中工作哈希和HashSet的方式時,我有些懷疑。在Java中哈希函數的誤解和在HashSet中包含的工作

我們知道下面的假設,我們應該fullfil:

if elements are equals then also their hashes are equals 

換句話說:

a.equals(b) ---> a.hashCode() == b.hashCode() 

但是,我們不能說

a.hashCode() == b.hashCode() ---> a.equals(b) 

的問題是我讀過的包含HashSet計算散列h,並且th只搜索元素中的哈希h。它不會將equals稱爲h的桶元素 - 它僅包含hashCode。這意味着我們contains可以返回錯誤的答案,如果元素具有等於散列,但equals返回false(正如我上面提到的,這是可能的)。

+0

'a.hashCode() == b.hashCode()'並不意味着'a.equals(b)' – dehasi

+0

哈希碼不用於兩個值之間的比較。它只是用來均勻地分割值,以便可以檢查和比較數量較小的數值,從而更快速地進行比較。 – jiaweizhang

回答

1

雖然這是事實,

a.hashCode() == b.hashCode() doesn't mean that a.equals(b)

致電時包含在Java中的HashSet方法,其底層HashMap的ContainsKey方法被調用。這個方法檢查該對象的節點爲空,getNode功能還檢查關鍵字等於

final Node<K,V> getNode(int hash, Object key) { 
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k; 
    if ((tab = table) != null && (n = tab.length) > 0 && 
     (first = tab[(n - 1) & hash]) != null) { 
     if (first.hash == hash && // always check first node 
      ((k = first.key) == key || (key != null && key.equals(k)))) 
      return first; 
     if ((e = first.next) != null) { 
      if (first instanceof TreeNode) 
       return ((TreeNode<K,V>)first).getTreeNode(hash, key); 
      do { 
       if (e.hash == hash && 
        ((k = e.key) == key || (key != null && key.equals(k)))) 
        return e; 
      } while ((e = e.next) != null); 
     } 
    } 
    return null; 
} 
+0

嗯,所以在相等的情況下,它會調用'equals'? (爲了確保平等是真的)? – user8820082

+0

確切地說,就像剛纔檢查哈希平等不會得到保證一樣。 –

+0

但是,當哈希值不相等時,我們知道對象是不同的,因此沒有意義調用equals。是嗎? – user8820082

0

首先,你應該瞭解對象如何HashMap的作品在Java:

  1. 的HashMap中java將key和value對象存儲在一個bucket中,作爲實現嵌套接口Map.Entry的Entry類的一個對象。

  2. 當put()方法用於存儲(Key,Value)對時,HashMap實現會調用Key對象的哈希碼以計算用於查找存儲Entry對象的存儲區的哈希值。當使用get()方法檢索值時,使用key對象來計算散列,然後使用該散列查找存儲該特定鍵的存儲區。

  3. HashMap密鑰對象用於比較,同樣使用equals()方法Map知道如何處理衝突衝突(散列衝突意味着多個密鑰具有相同的散列值,因此分配給同一個桶)在這種情況下對象被存儲在鏈接列表

  4. hashCode方法有助於尋找其中該密鑰被存儲桶中,等於方法有助於尋找因爲可能存在存儲在單個桶多於一個鍵 - 值對的權利密鑰。

所以現在來您的問題,當你打電話

i。如果元素是相等的,那麼他們的哈希值等於 ii。 a.equals(b)---> a.hashCode()== b.hashCode() iii。 a.hashCode()== b.hashCode()---> a。等於(b)

Blockquote並非總是如此,兩個不相等的對象具有相同的哈希碼完全合法。它被HashMap用作「第一遍過濾器」,以便地圖可以使用指定的鍵快速找到可能的條目。如果兩個不相等的對象不能有相同的哈希碼,那麼這會限制你2^32個可能的對象。

現在來HashSet的

塊引用一組是唯一對象的集合,與Java定義在HashSet的唯一兩個對象將不等於