2014-11-24 58 views
3

我們有一個名爲Subscriber的類,它擴展了「HashMap」。我們在列表中有很多這個類的實例,每個實例都有一組設置爲地圖的條目,其中一個是「狀態」。我的HashMap如何有一個重複的密鑰?

我們的程序通過調用訂閱服務器上的方法來更新「狀態」值,該方法對HashMap進行了簡單的放置。

我們的程序可以在沒有任何問題的情況下運行多天(幾周),但有時我們在系統的某些其他部分看到了奇怪的行爲,它使用HashMap中的數據。對於我們來說,它看起來好像在一個或多個Subscriber實例中有一個重複的密鑰。

我們設法創建一個jmap轉儲,並根據轉儲查找我在查看VisualVM中的轉儲時設置了兩次「狀態」。

Screenshot of VisualVM

我們目前正在運行的Java版本:1.7.0_25(甲骨文)

這怎麼可能?或者我讀了VisualVM錯誤?

+2

您是從多個主題寫入地圖嗎? – 2014-11-24 11:57:40

+0

什麼課程被用作你的鑰匙地圖? – AlexR 2014-11-24 11:59:33

+1

@JonSkeet是的,我是 – goddva 2014-11-24 12:01:08

回答

1

除了線程問題有這種結果的一個明確的路線:

class Key implements CharSequence { 

    private byte[] key; 

    public Key(String key) { 
     // Take a copy of the bytes of the string. 
     this.key = key.getBytes(); 
    } 

    @Override 
    public int length() { 
     return key.length; 
    } 

    @Override 
    public char charAt(int index) { 
     return (char) key[index]; 
    } 

    @Override 
    public CharSequence subSequence(int start, int end) { 
     return new Key(new String(key).substring(start, end)); 
    } 

    // Allow the key to change. 
    public void setKey(String newValue) { 
     key = newValue.getBytes(); 
    } 

    @Override 
    public String toString() { 
     return new String(key); 
    } 
} 

public void test() { 
    Map<CharSequence, String> testMap = new HashMap<>(); 
    Key aKey = new Key("a"); 
    Key bKey = new Key("b"); 
    testMap.put(aKey, "a"); 
    testMap.put(bKey, "b"); 
    bKey.setKey("a"); 
    System.out.println(testMap.keySet()); 
} 

這是從根本上讓地圖可變的鑰匙,使他們能夠後,他們將被添加到地圖改變。

雖然這可能不是你所面臨的問題(多線程問題更有可能),但這是對問題的真實答案我的HashMap如何有一個重複的鍵?

+0

這是問題標題的答案。在屏幕截圖中,可以看到該鍵是一個字符串,因此它不是完整問題的答案;-) – cello 2014-11-24 12:25:48

+0

除截圖清楚地顯示鍵的類型是字符串外。 – 2014-11-24 12:25:55

相關問題