2015-08-31 53 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