2013-08-07 69 views
4

爲什麼可以循環TreeMap的keySet並獲得.containsKey == falseJava TreeMap包含一個鍵,但containsKey調用返回false(即使鍵完全相同也是不變的對象)

for (Object thisObject : map.keySet()) { 
    if (!map.containsKey(thisObject)) { 
     System.out.println("This line should be never reached."); 
    } 
} 

經過很多次,很多不同的迭代和調用這條線被擊中。 A map.get(thisObject)將返回null。 但調試顯示密鑰(相同的引用,值和散列)和實際值在地圖中。該地圖是一個小的(25種元素)TreeMap<Long, Double>

UPDATE:

由於猜測通過@rgettman那裏有在樹形圖的構建中使用的排序Comparator自定義的(沒有看到它,因爲它是從另一個構造類)。這種比較只是(我猜的)副本從here

更改粘貼Comparator

public int compare(Object a, Object b) { 

    if((Double)base.get(a) > (Double)base.get(b)) { 
     return 1; 
    } else if((Double)base.get(a) == (Double)base.get(b)) { 
     return 0; 
    } else { 
     return -1; 
    } 
    } 

... 
    } else if(base.get(a).equals(base.get(b))) { 
     return 0; 
... 

解決了這個問題。之所以出現這個問題,是因爲在數百萬次操作之後出現的情況是,沒有任何情況下地圖對於兩個不同的鍵具有兩個相似的值,因爲在上下文中這是不太可能的。

所以在:

25151l, 1.7583805400614032 
24827l, 1.7583805400614032 

失敗。

感謝您的幫助!

+1

你可以嘗試將==改爲.equals嗎? –

+0

@RameshK我的意思是,OP已經確認它是相同的參考,所以不應該有'=='的問題,應該在那裏? –

+0

失敗的關鍵值是什麼? – rgettman

回答

0

我剛剛執行了代碼,這種情況確實給我返回了真實

  TreeMap<Long,Double> otm = new TreeMap<Long, Double>(); 
      otm.put(1L, 1.0); 
      otm.put(2L, 2.0); 

     for (Object thisObject : otm.keySet()) { 
       System.out.println(otm.containsKey(thisObject)); 
     }  

您能否給我們提供您在TreeMap中輸入的數據。由於

這是containKey(對象鍵)實現從JavaDoc中

的containsKey

布爾的containsKey(對象鍵)

返回true,如果此映射包含的映射指定的鍵。

更正式地說,當且僅當此映射包含鍵k的映射 返回true,使得 (鍵== NULL滿足K == NULL:?key.equals(K))。 ( 最多隻能有一個這樣的映射。)

參數:

key - key whose presence in this map is to be tested Returns: 
true if this map contains a mapping for the specified key Throws: 
ClassCastException - if the key is of an inappropriate type for this map (optional) 
NullPointerException - if the specified key is null and this map does not permit null keys (optional 

希望有所幫助。

+1

如果問題在於OP添加的特定對不在您的示例中,該怎麼辦?關鍵是OP *知道它應該返回true,但想知道爲什麼他的特定情況不是。嘗試一些其他的隨機案例根本不回答這個問題。 –

+0

@ DennisMeng我很想了解這種特定的對。我的觀點是OP可能沒有正確實施它。這就是爲什麼我想看到具體的情況。你遇到過這種情況嗎?如果是的話,我會很感激,如果你可以讓我知道相同的。 – JNL

+0

我想,但是「確定你沒有犯錯誤」和「我試過這個其他情況並且對我工作正常」之間有區別 –

0

您必須對支持entrySet()/Map.Entry進行更改,從而更改密鑰訂單,從而導致搜索失敗containsKey

0

大多數這些實現類都依賴於hashCode()和equals()被支持和正確。

如果你真的擁有與對象相同的哈希碼,請嘗試匹配相等。我建議的答案是他們不匹配。

否則,場景應該足夠小,以便發佈對象和/或其各自的哈希碼和等於方法。

+0

Long的哈希碼基於它的值 public int hashCode(){ return(int)(value ^(value >>> 32)); }' – user2661619

相關問題