在修改它时迭代Koloboke Hashmap

时间:2015-08-31 17:33:42

标签: java hashmap koloboke

我有一个大的hashmap(~3M条目),我正在使用Koloboke LongIntMap来实现它。我需要迭代地图中的键,但能够沿途修改地图。一些修改可能是结构性的(添加/删除条目)。

除非绝对必要,否则我不想为同步实施或复制的密钥列表付出代价。我知道迭代结果会或多或少随机,遗漏一些键,可能会使用其他键两次,这在我们的应用程序中不是问题。

有没有办法实现这样的地图迭代?提前感谢任何意见。

1 个答案:

答案 0 :(得分: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));
}