连续循环遍历 HashMap 需要什么代码?
目前,我的代码导致间歇性的 ConcurrentModificationException 错误,可能是因为我循环遍历 HashMap 的方式:
for (Map.Entry<String, Entity> entry : entities.entrySet()) {
String key = entry.getKey();
Entity item = entry.getValue();
if (item.isDestroyed()){
entities.remove(key);
ViewManager.getInstance().removeItem(key);
//INSTRUCT THE ENTITY TO PERFORM IT'S DESTROYED BEHAVIOR item.Destroyed()
} else {
item.update(1);
ConsoleItem ci = new ConsoleItemImpl(item.getIdentifier(), item.getLocation(), ColorStringConverter.getInstance().StringToColor(item.getSide()), item.getAngle(), item.getShape(), item.toString(), item.isDestroyed(), item.isDamaged());
ViewManager.getInstance().updateItem(ci);
}
item.update(1);
}
// updateInfo call
ViewManager.getInstance().updateInfo(summary());
}
How does one Continuous loop through a HashMap and避免 ConcurrentModificationException 错误?
Currently my code is causing intermittent ConcurrentModificationException errors, probably because of the way I am looping through the HashMap:
for (Map.Entry<String, Entity> entry : entities.entrySet()) {
String key = entry.getKey();
Entity item = entry.getValue();
if (item.isDestroyed()){
entities.remove(key);
ViewManager.getInstance().removeItem(key);
//INSTRUCT THE ENTITY TO PERFORM IT'S DESTROYED BEHAVIOR item.Destroyed()
} else {
item.update(1);
ConsoleItem ci = new ConsoleItemImpl(item.getIdentifier(), item.getLocation(), ColorStringConverter.getInstance().StringToColor(item.getSide()), item.getAngle(), item.getShape(), item.toString(), item.isDestroyed(), item.isDamaged());
ViewManager.getInstance().updateItem(ci);
}
item.update(1);
}
// updateInfo call
ViewManager.getInstance().updateInfo(summary());
}
How does one continuously loop though a HashMap and avoid a ConcurrentModificationException error?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
循环遍历地图时无法修改地图。您必须复制地图,使用 ConcurrentHashMap,或使用 迭代器< /a>.如果是在多线程环境下,那么可以在synchronized块中进行修改。
另一种选择是使用迭代器。
我用下面的迭代器重写了 for for 循环:
我不确定连续循环 HashMap 的部分。哈希映射具有有限的键集,因此通常可以循环遍历键集。如果您出于某种原因想要连续循环,那么您需要首先告诉我们其背后的原因以及该连续循环的终止条件(它不可能是永远,不是吗?)。
You cannot modify a map while looping through it. You either have to make a copy of the map, use a ConcurrentHashMap, or use an iterator. If it is in a multi threaded environment, then you can do the modification in a synchronized block.
Another option is to use an iterator.
I rewrote your for for loop with an iterator below:
I am not sure about the part of continuously looping a HashMap. A hash map has a finite set of keys, so you loop through the key set generally. If you for some reason want to loop continuously then you need to first tell us the reason behind it and also the terminal condition of that continuous loop (it cant really be forever, can it?).
正如其他答案中所述,使用基于迭代器的 for 循环而不是 for-each 循环是避免 ConcurrentModificationExemptions 的最佳选择。至于无限循环,请查看循环方法。它接受一个 Iterable(例如 HashMap)并返回一个 Iterator,该迭代器不断循环数据,直到 Iterable 为空或中断循环。
As documented in the other answers, using a Iterator based for-loop, instead of a for-each loop, is your best bet for avoiding ConcurrentModificationExemptions. As for the infinite looping, have a look at the cycle method in Guava's Iterators static utility class. It takes an Iterable (such as a HashMap) and returns an Iterator that continuously loops over the data until either the Iterable is empty or you break the loop.
使用迭代器和 while 循环怎么样?
how about using an iterator and while loop?
您不能在循环时调用 Remote(key) 方法,但可以通过迭代器删除条目:
You cannot call remote(key) method while looping, but you can remove entries via an iterator:
假设您仅在线程中访问映射,请使用迭代器,正如其他人建议的那样。
我在考虑迭代哈希图时的性能,
所以我对 10^6 随机 Long 进行了 25 次迭代的快速测试,并删除了其中的 10%,
使用不同的映射实现:ConcurrentHashMap、HashMap、LinkedHashMap
和一个树状图。
链接的哈希图据说是为迭代而定制的,而且它似乎是最有效的。我认为峰值是由于 gc 造成的。
...但差异比我预期的要小。
Assuming that you are accessing the map in only on thread, use an iterator, as the other guys suggest.
I was thinking about the performance when iterating over a hashmap,
so i did a quick test of 25 iterations over 10^6 random Longs and removing 10% of then,
using different map implementations: ConcurrentHashMap, HashMap, LinkedHashMap
and a TreeMap.
The linked hashmap is supposedly tailored for iterating, and it seems to be the most efficient. I suppose the spikes are due to gc.
...but the differences are smaller than I had anticipated.