2012-01-08 2 views
2

HashMap에서 항목을 제거하려고하면 Concurrent Modification Exception이 발생합니다. HashMap을 통해 반복하는 동안 항목을 제거하면이 예외가 트리거된다는 것을 알고 있지만 이전 항목을 새 항목으로 바꿔야합니다. 내가 어떻게 할 수 있니? 어쩌면 countNumberOfEachCharacter HashMap의 사본을 만들고, 원래 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);                
} 
+3

질문을보다 쉽게 ​​읽을 수 있도록 시간을내어주십시오. –

+0

'ConcurrentHashMap'을 사용하십시오. –

+0

@ Eng.Fouad 동시 액세스가 없기 때문에 문제가 해결되지 않습니다. 그는 단지 그것을 반복하고 요소를 제거합니다. –

답변

1

...하지만 난 내가 "대체"에서 받아 새로운

으로 오래된 항목을 교체해야합니다 (당신이 인용 한 코드에서)를 남아 그 같은, 그것은 단지 값이 다릅니다. 그렇다면 setValueMap.Entry 개체로 호출하면 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

Collection 반복하는 동안, 당신은 단지 Iterator#remove 방법을 사용하여 요소를 제거 할 수 있습니다. 맵이 구조적으로 어떤 시간이 변경되면 반복자의 작성 후 : 이것은 또한이 클래스의 모든 "모음보기 방법"르파에 의해 반환 HashMap

반복자의 클래스의 javadoc에 설명되어 있습니다 , 어떤 방법 으로든 반복자 자체의 remove 메소드를 통하는 경우를 제외하고, 반복자는 ConcurrentModificationException을 발생시킵니다. 따라서, 동시 변경을하면 (자), 반복자는 (당신이 뭘 하려는지에 대한

또한 미래에 예측할 수없는 시점 에 예측할 수없는 동작이 발생하는 위험을 회피 신속하고 깨끗하게 실패보다는 = 값을 업데이트) 제거 할 필요가 없습니다. 그냥 HashMap#put 방법

과 지정된 키를이 맵에 관련 지정된 값의 자바 독에 설명 된대로 값을 업데이트하는, 그 키와 업데이트 된 값을 put를 호출합니다. 지도에 이전에 키 매핑이 포함 된 경우 이전 값은 으로 바뀝니다.

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 
관련 문제