在删除和更新集合时遍历HashMap



我有一个计数映射,用于跟踪字符串中的字符数。我想在这个映射上迭代,减少当前访问的字符计数,如果它达到零就删除它。

如何在Java中实现?

HashMap<Character, Integer> characterCount = new HashMap<>();
characterCount.put('a', 2);
characterCount.put('b', 1);
characterCount.put('c', 1);
Iterator<Map.Entry<Character, Integer>> iterator = characterCount.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<Character, Integer> entry = iterator.next();
// Decrement the chosen character from the map
if (entry.getValue() == 1) {
iterator.remove();
} else {
characterCount.put(entry.getKey(), entry.getValue() - 1);
}
// Call some logic the relies on the map with the remaining character count.
// I want the characterCount.size() to return zero when there is no character with count > 0
doSomeLogic(characterCount);
// Restore the character to the map
characterCount.put(entry.getKey(), entry.getValue());
}

上面的代码产生一个ConcurrentModificationException

由于Map#entrySet返回映射中映射的视图,因此直接设置Entry的值来更新它。

if (entry.getValue() == 1) {
iterator.remove();
} else {
entry.setValue(entry.getValue() - 1);
}

这是一种方法。当条目变为null时,Map.computeIfPresent将删除该条目。使用三元运算符,要么减少值,要么将当前为1的值替换为null(即将减少)。

Map<Character, Integer> map = new HashMap<>();
map.put('a', 2);
map.put('b', 1);
map.put('c', 1);
map.computeIfPresent('c', (k,v)-> v == 1 ? null : v-1);
map.computeIfPresent('a', (k,v)-> v == 1 ? null : v-1);
System.out.println(map);

打印

{a=1, b=1}

那么,这就是它如何为你工作的,替换你的迭代器和while循环。

for (char ch : characterCount.keySet()) {
characterCount.computeIfPresent(ch, (k,v)-> v == 1 ? null : v-1);
}

最新更新