在修改 Koloboke Hashmap 的同时对其进行迭代
Iterate Koloboke Hashmap while modifying it
我有一个很大的散列图(~3M 条目),我正在使用 Koloboke LongIntMap
来实现它。我需要迭代地图中的键,但能够沿途修改地图。一些修改可能是结构性的(adding/deleting 个条目)。
除非绝对必要,否则我不想为同步实施或复制密钥列表付出代价。我知道迭代结果或多或少是随机的,遗漏了一些键,可能两次取其他键,这在我们的应用程序中不是问题。
有没有办法实现这样的地图迭代?在此先感谢您的任何意见。
通过修改(键删除和更新,但不是添加)遍历 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));
}
我有一个很大的散列图(~3M 条目),我正在使用 Koloboke LongIntMap
来实现它。我需要迭代地图中的键,但能够沿途修改地图。一些修改可能是结构性的(adding/deleting 个条目)。
除非绝对必要,否则我不想为同步实施或复制密钥列表付出代价。我知道迭代结果或多或少是随机的,遗漏了一些键,可能两次取其他键,这在我们的应用程序中不是问题。
有没有办法实现这样的地图迭代?在此先感谢您的任何意见。
通过修改(键删除和更新,但不是添加)遍历 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));
}