2015-08-31 55 views
1

我有一個大的HashMap(〜3M條目),並使用Koloboke LongIntMap來實現它。我需要迭代地圖中的鍵,但能夠沿途修改地圖。一些修改可能是結構化的(添加/刪除條目)。迭代Koloboke Hashmap,同時修改它

我不想支付同步實現或複製密鑰列表的價格,除非它是絕對必要的。我知道迭代結果會或多或少是隨機的,會遺漏一些密鑰,也可能會使用其他密鑰兩次,這在我們的應用程序中並不是問題。

有什麼辦法可以實現這樣的地圖迭代?預先感謝您的任何意見。

回答

2

慣用的方式來遍歷Koloboke收集與修改(鍵清除和更新,但不會增加)是通過cursor

for (LongIntCursor cur = map.cursor(); cur.moveNext();) { 
    long key = cur.key(); 
    int value = cur.value(); 
    if (checkSomething(key, value)) { 
     cur.remove(); // remove the entry 
    } else { 
     cur.setValue(newValue); // update the value 
    } 
} 

添加是不支持的,它應該拋出ConcurrentModificationException,以同樣的方式如java.util.HashMap那樣。之所以如此 - 如果添加會觸發完整的映射重新散列,則無法正確完成迭代。

作爲一種變通方法,你可以收集你想迭代過程中插入到地圖中的條目,而迭代後進行批量插入:

// You could get primitive lists from fastutil, gs, hppc or trove 
LongList keysToPut = keysToPutThreadLocal.get(); 
keysToPut.clear(); 
IntList valuesToPut = valuesToPutThreadLocal.get(); 
valuesToPut.clear(); 

for (LongIntCursor cur = map.cursor(); cur.moveNext();) { 
    long key = cur.key(); 
    int value = cur.value(); 
    if (checkSomething(key, value)) { 
     cur.remove(); // remove the entry 
    } else { 
     // want to insert a <newKey, newValue> entry 
     keysToPut.add(newKey); 
     valuesToPut.add(newValue); 
    } 
} 
// bulk insert 
for (int i = 0, toPut = keysToPut.size(); i < toPut; i++) { 
    map.put(keysToPut.get(i), valuesToPut.get(i)); 
} 
+0

感謝清理增加的原因不支持。我還需要允許添加,並且願意失去迭代保證。我猜如果沒有挖掘源碼,就沒有辦法呢? –

+0

你可以使用另一個lib,其中一些可能不會拋出'ConcurrentModificationException'(AFAIR hppc聲稱它不會隱藏任何細節,基本上允許任何,甚至不安全的使用)。 – leventov