📅  最后修改于: 2023-12-03 15:23:38.060000             🧑  作者: Mango
在 Java 中,如果我们需要从一个 HashMap
中删除一些键值对,我们需要使用 Iterator
迭代器来删除条目。使用迭代器,我们可以安全地迭代一个集合并进行删除操作,而不会影响其它正在进行的迭代操作。
然而,当我们需要删除 HashMap
中的一些值时,我们就面临一个问题。使用迭代器删除键值对是可以的,但是如果我们仅仅要删除值,则会有一些问题。考虑以下代码:
Map<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(4, "four");
for (String value : map.values()) {
if (value.equals("two") || value.equals("three")) {
map.values().remove(value);
}
}
System.out.println(map);
输出结果应该是:
{1=one, 4=four}
然而,我们却得到了一个 ConcurrentModificationException
异常!
原因是在遍历 HashMap
中的值时删除了值,而且是通过 HashMap
的 values()
方法来遍历的。在遍历过程中改变了 HashMap
的大小,而不是通过迭代器进行删除。因此,遍历过程就不再有效了。
我们可以通过遍历 HashMap
的键值对来解决这个问题。以下是一种解决方案:
Map<Integer, String> map = new HashMap<>();
map.put(1, "one");
map.put(2, "two");
map.put(3, "three");
map.put(4, "four");
Iterator<Map.Entry<Integer, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Integer, String> entry = iterator.next();
if (entry.getValue().equals("two") || entry.getValue().equals("three")) {
iterator.remove();
}
}
System.out.println(map);
输出结果应该是:
{1=one, 4=four}
现在我们成功地从 HashMap
中删除了键值为 "two"
和 "three"
的条目,而不会抛出异常了!
在迭代 HashMap
的值时,应该使用键值对遍历,并且使用迭代器进行删除操作。如果需要删除值而非键值对,应该使用键值对遍历并使用迭代器删除操作。这样设计是为了防止在并发修改 HashMap
的大小时,修改操作导致迭代器失效。