Java: 使用 HashMap 迭代器比使用 ConcurrentHashMap 有什么优势?
Java: What is the advantage of using HashMap iterator over ConcurrentHashMap?
我有一个单线程程序,它使用一个 Map,其中的项目在迭代时被一个接一个地删除。我读过可以在这里使用迭代器来避免 ConcurrentModificationException
但为什么不使用 ConcurrentHashMap 来代替它似乎更干净?
我的代码:
private final Map<Integer, Row> rowMap;
.....
private void shutDown() {
for (Integer rowNumber : rowMap.keySet()) {
deleteRow(rowNumber)
}
}
....
对于我的场景,使用迭代器意味着将其声明为最终的,因此 closeRow() 和 deleteRow() 方法可以访问它以将其删除。此外,iterator.remove() 方法不会 return 正在删除的项目的值,这在我的情况下是必需的。
我的问题是,为了不抛出 ConcurrentModificationException,最有效的方法是什么?是使用迭代器还是让 rowMap 成为 ConcurrentHashMap?
这是一个相当简单的迭代器模式。
Iterator<Map.Entry<Integer,Row>> it = rowMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer,Row> ent = it.next();
Integer key = ent.getKey();
Row row = ent.getValue(); // before the remove
it.remove();
// ... do what you want with key and row;
}
因此,我们使用显式迭代器遍历映射,这允许我们在迭代期间使用迭代器的 remove
方法。我们正在迭代映射的“条目集”视图,这使我们能够从单个迭代器中检索键和值。
public Set<Map.Entry<K,V>> entrySet()
Returns a Set view of the mappings contained in this map. The set is
backed by the map, so changes to the map are reflected in the set, and
vice-versa. If the map is modified while an iteration over the set is
in progress (except through the iterator's own remove operation, or
through the setValue operation on a map entry returned by the
iterator) the results of the iteration are undefined.
只有在线程间共享时才使用 ConcurrentHashMap
。
在单线程中,当使用迭代器修改对象时抛出CurrentModificationException
。
有两种方法可以从列表和地图等集合中删除元素。一种是在集合上调用 remove。另一个是使用迭代器。但它们不能一起使用。如果您使用集合对象的 remove 方法删除一个元素,它会使迭代器的状态无效。
List<Integer> list = new ArrayList(List.of(1,2,3,4,5));
Iterator<Integer> it = list.iterator();
list.remove(0);
while(it.hasNext()){
System.out.print(it.next());
}
例外情况:
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at Main.main(Main.java:15)
我有一个单线程程序,它使用一个 Map,其中的项目在迭代时被一个接一个地删除。我读过可以在这里使用迭代器来避免 ConcurrentModificationException
但为什么不使用 ConcurrentHashMap 来代替它似乎更干净?
我的代码:
private final Map<Integer, Row> rowMap;
.....
private void shutDown() {
for (Integer rowNumber : rowMap.keySet()) {
deleteRow(rowNumber)
}
}
....
对于我的场景,使用迭代器意味着将其声明为最终的,因此 closeRow() 和 deleteRow() 方法可以访问它以将其删除。此外,iterator.remove() 方法不会 return 正在删除的项目的值,这在我的情况下是必需的。
我的问题是,为了不抛出 ConcurrentModificationException,最有效的方法是什么?是使用迭代器还是让 rowMap 成为 ConcurrentHashMap?
这是一个相当简单的迭代器模式。
Iterator<Map.Entry<Integer,Row>> it = rowMap.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<Integer,Row> ent = it.next();
Integer key = ent.getKey();
Row row = ent.getValue(); // before the remove
it.remove();
// ... do what you want with key and row;
}
因此,我们使用显式迭代器遍历映射,这允许我们在迭代期间使用迭代器的 remove
方法。我们正在迭代映射的“条目集”视图,这使我们能够从单个迭代器中检索键和值。
public Set<Map.Entry<K,V>> entrySet()
Returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress (except through the iterator's own remove operation, or through the setValue operation on a map entry returned by the iterator) the results of the iteration are undefined.
只有在线程间共享时才使用 ConcurrentHashMap
。
在单线程中,当使用迭代器修改对象时抛出CurrentModificationException
。
有两种方法可以从列表和地图等集合中删除元素。一种是在集合上调用 remove。另一个是使用迭代器。但它们不能一起使用。如果您使用集合对象的 remove 方法删除一个元素,它会使迭代器的状态无效。
List<Integer> list = new ArrayList(List.of(1,2,3,4,5));
Iterator<Integer> it = list.iterator();
list.remove(0);
while(it.hasNext()){
System.out.print(it.next());
}
例外情况:
Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1013)
at java.base/java.util.ArrayList$Itr.next(ArrayList.java:967)
at Main.main(Main.java:15)