2012-03-22 155 views
2

在什麼情況下給出了hashCode和equals()的正確實現,下面的代碼可以返回false嗎?java hashtable包含奇怪

myLinkedHashMap.containsKey(myLinkedHashMap.keySet().iterator().next()) 
+0

「確定性」是否指「正確」? – 2012-03-22 21:29:00

+0

它在這種情況下並不重要,因爲它是同一個對象,對吧?所以只要對同一個對象的2次調用產生相同的hashCode,就應該返回true。但是,是的,這也是正確的。 – 2012-03-22 21:30:01

+1

但「確定性」並不意味着「對同一對象的2個調用產生相同的hashCode」。關於'ArrayList .hashCode'沒有任何*非確定性的*,但看到我的答案... – 2012-03-22 21:34:44

回答

7

我可以想到的最可能的情況是即使hashCode是「確定性」,它可能基於可變字段。如果您在Map中更改用於計算hashCode的字段,那麼您將無法再找到它。

編輯:應澄清你'通常'將無法找到它了。偶爾它仍然可以工作,因爲兩個數字仍然可以重新進入同一個桶。當然,這隻會增加混亂髮生!

+0

是的,突變。謝謝。 – 2012-03-22 21:40:20

2

目前尚不清楚你所說的「確定性」,但任何哈希變化的突變的關鍵是什麼意思,它已經插入到哈希表後很容易有這種效果。

import java.util.*; 

public class Test { 
    public static void main(String[] args) { 
    List<String> strings = new ArrayList<String>(); 
    Map<List<String>, String> map = new LinkedHashMap<List<String>, String>(); 

    map.put(strings, ""); 
    System.out.println(map.containsKey(map.keySet().iterator().next())); // true 
    strings.add("Foo"); 
    System.out.println(map.containsKey(map.keySet().iterator().next())); // false 
    } 
} 

ArrayList<T>哈希碼是確定的,但是,這並不意味着它不會改變,如果列表中的內容發生變化。

1

如果您的hashCodeequals彼此不同意,則可能返回錯誤。例如,如果equals方法總是返回false,則這將返回false,因爲沒有任何對象與映射中的鍵相等。

希望這會有所幫助!

2
  1. 如果hashCode()是基於是可變和這些屬性在插入後改變實例屬性,迭代過程中hashCode()調用將返回不同的東西。 equals()應該基於這些相同的屬性,它也會失敗。

  2. 當另一個線程已經刪除了所有下一個在迭代中間的Map項目,將有沒有更多的next()

我不會使用hashCode()值作爲鍵,我會把你自己的對象。

+0

沒有線程。 – 2012-03-22 21:31:22

+1

並不重要,如果你正在考慮的特定實例不使用一個線程,你的**問題**問什麼時候會發生,這是可能發生的一種情況。 – 2012-03-22 21:35:13

0

您可能需要先檢查hasNext()。

+0

不,它在那裏。絕對有元素。 – 2012-03-22 21:32:13

3

我看到的每個散列算法都是「確定性」的,因爲對於給定的一組輸入值,您可以得到相同的散列值。

如果根據對象的可變屬性計算哈希代碼,則哈希代碼在哈希映射後會發生變化,如果這些可變屬性中的任何一個發生更改。

0

您可以在獲取第一個鍵和調用containsKey之間刪除另一個線程中的第一個鍵。