2011-03-04 2 views
1

다음 코드는 Hashtable에서 요소를 안전하게 제거하는 방법입니까?반복에서 해시 테이블의 요소를 제거하십시오.

Enumeration keys = siCache.keys(); //siCache is Hashtable 

    while(keys.hasMoreElements()) 
    { 
     String k = (String) keys.nextElement(); 
     Object v = siCache.get(k); 

     if(condition) siCache.remove(k); 

    } 
+0

왜 요소가 항상 '문자열'에 캐스트되는지 알 수 없습니다. 'HashTable.remove'는'toString'이 아닌 키 자체를 기대합니다. 만약 당신의 상태가 어떤 이유로'String'을 필요로한다면,'HashTable.remove'에 대한 명령으로 사용하지 마십시오. –

+0

처럼 보입니다. 안전하지는 않지만 특별한 이유가 있습니까? – rkg

+1

@Jon_darkstar Q : toString()은 String으로 캐스팅해야합니까? A : 아무것도. – EJP

답변

2

키를 열거하면서 Hashtable에서 요소를 제거하는 것은 잠재적으로 위험합니다. 여기에 자바 독의 말씀입니다 :

"따라서, 동시 변경을하면 (자), 반복자는 오히려 장래의 예측할 수없는 시점에있어 예측할 수없는 동작이 발생하는 위험을 회피하기 위해서, 즉시 한편 솜씨 실패 열거가 돌아왔다. Hashtable의 키와 엘리먼트 방식은 실패하지 않습니다. "

의미는 분명합니다. 그렇게하면 임의의 비 결정적 동작이 가능합니다.

솔루션 :

  • 는 J2SE를 사용하는 경우, keySet()를 사용합니다. 또는 더 나은 여전히 ​​사용하지 마십시오 Hashtable.
  • J2ME를 사용하는 경우 제거 할 키 목록을 작성한 다음 나중에 제거하거나 열심히기도하십시오.
-1

안전합니다. 그러나 무엇이 당신을 생각하게 만들지 않았을까요 ??

은 다음 코드로 테스트되었습니다.

public static void main(String[] args) { 
     // TODO Auto-generated method stub 

     Hashtable siCache = new Hashtable(); 
     siCache.put("key", "value"); 
     siCache.put("key1", "value1"); 
     Enumeration keys = siCache.keys(); //siCache is Hashtable 

     while(keys.hasMoreElements()) 
     { 
      String k = (String) keys.nextElement(); 
      Object v = siCache.get(k); 

      if(true) siCache.remove(k); 

     } 
     System.out.println(siCache.size()); 
    } 

출력 : 0

+1

아니오, 그것은 안전하지 않다. – EJP

+0

그리고 예제는 아무것도 증명하지 못합니다. –

5

이 엔트리 세트, 키 세트, 또는 값 세트의 반복자를 사용하여 Iterator.remove()를 호출합니다. 사용 사이에 뚜렷한 차이가있다

+1

아니요, 또 다른 안전한 기술이 있습니다 : 키 세트의 반복자와'remove()'메소드를 사용하는 것입니다. :) – rlibby

+0

완전한 예를 들어 주겠니? 나는 자바를 처음 사용합니다. 감사의 말 : – pierrotlefou

+0

또 다른 안전한 기법 : VALUE와 그 remove() 메소드의 반복자를 사용한다. :) – Timmos

1

...

Enumeration keys = siCache.keys(); 

및 사용 ...

Iterator iterator = siCache.entrySet().iterator() 

옵션 1이 반복하는 동안 컬렉션의 요소를 제거 할 때 반면하는 ConcurrentModificationException를 포기하지 않습니다 옵션 2가됩니다.

이유는 ... 당신이 예제에서 키 열거 형을 만들 때 그것은 테이블 자체에 대한 수정 사항과 동기화되지 않는 테이블 키 세트의 리터럴 복사본이라고 믿습니다.

이것은 문제 일 수도 있고 아닐 수도 있습니다. 테이블을 동시에 사용하는 경우 컬렉션 반복기를 사용하도록 전환 할 수 있습니다.

관련 문제