当我尝试从HashMap中删除项目时,我得到了Concurrent Modification Exception。我知道在迭代过程中通过HashMap删除项目会触发此异常,但我需要用新的项目替换旧项目。我怎样才能做到这一点 ?也许创建一个countNumberOfEachCharacter HashMap的副本,并循环通过原始的HashMap从复制HashMap中删除项目?
countNumberOfEachCharacter = new HashMap<Character,Character>();
if (countNumberOfEachCharacter.containsKey(word.charAt(i))) {
System.out.println("This character already exists");
for (Iterator it = countNumberOfEachCharacter.entrySet().iterator(); it.hasNext();) {
Map.Entry entry = (Map.Entry) it.next();
Object key = entry.getKey();
Object value = entry.getValue();
if (key.equals(word.charAt(i))) {
int toIncrease = Integer.parseInt(value.toString());
toIncrease++;
System.out.println("key "+key);
System.out.println("increased "+toIncrease);
countNumberOfEachCharacter.remove(word.charAt(i));
char c = Character.forDigit(toIncrease, 10);
countNumberOfEachCharacter.put(word.charAt(i),c);
}
}
}
else {
System.out.println("First time found this character");
char c = Character.forDigit(1, 10);
countNumberOfEachCharacter.put(word.charAt(i),c);
System.out.println("Stored "+word.charAt(i)+" with count "+c);
}
答案 0 :(得分:2)
在迭代Collection
时,您只能使用Iterator#remove
方法删除元素。这也在HashMap
所有这类&#34;集合视图返回的迭代器 方法&#34;快速失败:如果地图在任何地方进行了结构修改 创建迭代器之后的时间,除了通过之外的任何方式 迭代器自己的remove方法,迭代器会抛出一个 ConcurrentModificationException的。因此,面对并发 修改,迭代器快速而干净地失败,而不是 在不确定的时间冒着任意的,非确定性的行为 将来
此外,对于您要执行的操作(=更新值),您不必将其删除。只需使用该密钥和更新值调用put
,这将更新值,如HashMap#put
方法的javadoc中所述
将指定的值与此映射中的指定键相关联。如果 地图以前包含键的映射,旧值是 替换。
答案 1 :(得分:1)
...但我需要用新的项目替换旧项目
我从“替换”(以及你引用的代码)中取出键保持不变,它只是不同的值。如果是这样,我不相信在Map.Entry
个对象上调用setValue
会导致ConcurrentModificationException
,所以你可以这样做。
更新:刚试过它,确实有效:
import java.util.*;
public class ReplaceMapEntryValue {
public static final void main(String[] args) {
Map m;
Iterator<Map.Entry> it;
Map.Entry entry;
// Create
m = new HashMap();
m.put("a", "alpha");
m.put("b", "beta");
// Update
it = m.entrySet().iterator();
while (it.hasNext()) {
entry = it.next();
if (entry.getKey() == "b") {
entry.setValue("bravo");
}
}
// Show
it = m.entrySet().iterator();
while (it.hasNext()) {
entry = it.next();
System.out.println("key = " + entry.getKey() + ", value = " + entry.getValue());
}
// Done
System.exit(0);
}
}
答案 2 :(得分:0)
地图的重点是你可以按键查找,你不必检查每个条目。
Map<Character, AtomicInteger> countNumberOfEachCharacter = new TreeMap<Character, AtomicInteger>();
String word = "the quick brown fox jumps over the lazy dog";
for (int i = 0; i < word.length(); i++) {
AtomicInteger count = countNumberOfEachCharacter.get(word.charAt(i));
if (count == null)
countNumberOfEachCharacter.put(word.charAt(i), new AtomicInteger(1));
else
count.incrementAndGet();
}
System.out.println("Character count: " + countNumberOfEachCharacter);
打印
Character count: { =8, a=1, b=1, c=1, d=1, e=3, f=1, g=1, h=2, i=1, j=1, k=1, l=1, m=1, n=1, o=4, p=1, q=1, r=2, s=1, t=2, u=2, v=1, w=1, x=1, y=1, z=1}
但是,由于您有一些固定数量的小字符,因此您甚至不需要使用地图
int[] countNumberOfEachCharacter = new int[Character.MAX_VALUE + 1];
String word = "the quick brown fox jumps over the lazy dog";
for (int i = 0; i < word.length(); i++)
countNumberOfEachCharacter[word.charAt(i)]++;
System.out.print("Character count: ");
for (int i = 0; i < countNumberOfEachCharacter.length; i++)
if (countNumberOfEachCharacter[i] > 0)
System.out.print(" " + (char) i + "=" + countNumberOfEachCharacter[i]);
System.out.println();
打印
Character count: =8 a=1 b=1 c=1 d=1 e=3 f=1 g=1 h=2 i=1 j=1 k=1 l=1 m=1 n=1 o=4 p=1 q=1 r=2 s=1 t=2 u=2 v=1 w=1 x=1 y=1 z=1