2013-11-27 3 views
0

나는 arraylist에있는 객체가 PowerUp입니다. 이것들을 클릭 할 수 있기를 원하고, 클릭하면 화면에서 제거되어 궁극적으로 arraylist에서 빠져 나옵니다. 나는 핸드북을 HealthPack 클래스에 넣었고, 다시 PowerUp을 확장했다. 클릭 한 특정 HealthPack에 액세스하려고 시도하고 해당 목록에서 제거하려고합니다. 계속 올바르게 작동하지 않거나 ConcurrentModificationException 중 하나가 계속 발생합니다. 나는 목록 모두에 추가가있을 때 HealthPack 클릭 갈 때배열 목록에서 클릭 된 객체 가져 오기

for (int i = 0; i < ((SurvivalMode) m).getPowerUps().size(); i++) { 
    PowerUp p = ((SurvivalMode) m).getPowerUps().get(i); 
    if (p.equals(hp)) { // HealthPack hp = this; 
     ((SurvivalMode) m).getPowerUps().remove(p); 
     addPoints(); 
    } 
} 

이 현재 코드가 실제로 ConcurrentModificationException을 발생하고, 다른 하나는 그것을 통해 반복된다 : 여기 내 코드는 내가 함께 작동하도록 노력하고 있습니다. 목록과 엉망인 메서드를 동기화하려고 시도했지만 도움이되지 않았습니다.

하나의 메서드가 목록에서 요소를 제거하려고 시도하거나 목록에서 요소를 반복하거나 목록에서 요소를 제거하거나 제거하는 중 하나의 메서드가 요소를 제거하려고하면 내 프로그램이 ConcurrentModificationException을 던지지 않게하려면 어떻게해야합니까?

EDIT : 여기
실제로 상품 ArrayList를 수정 추가적인 코드 :

if (powerups.size() >= 15 || isPaused()) return; 

    int gen = random.nextInt(10); 
    if (gen == 0) { 
     powerups.add(new HealthPack(this)); 
     addMouseListener(powerups.get(powerups.size() - 1).getMouseListener()); 
    } 
} 

일부 코드는 해당합니다 (ConcurrentModificationException을 던진다) 그리스트를 실제로 반복 :

for (PowerUp p : powerups) p.update(); 

현재 방법 : 여기에 curre가 있습니다. 클릭하면 목록에서 제거하려고 시도한 nt 메소드가 있지만 아무것도 삭제하지 않거나 잘못된 것을 제거하고 때로는 모든 메소드를 호출하기 때문에 너무 잘 작동하지 않습니다. 목록에있는 다른 PowerUp의의 :

Iterator<PowerUp> iter = ((SurvivalMode) m).getPowerUps().iterator(); 
while (iter.hasNext()) { 
    PowerUp p = (HealthPack) iter.next(); 
    if (p.equals(hp)) { 
     ((SurvivalMode) m).getPowerUps().remove(p); 
    } 
    CellDefender.getSounds().play(SoundType.HEALTH_PACK); 
    break; 
} 

업데이트 2 : 나는 최근 실제로 다른 점 내에 배열 목록을 복사됩니다 짓을하고 부분적으로 내 갱신 내에서 오류를 (줄이는 데 도움이 무엇
메소드) :

CopyOnWriteArrayList<PowerUp> cpowerups = new CopyOnWriteArrayList<PowerUp>(); 

for (int i = 0; i < powerups.size(); i++) { 
    cpowerups.add(powerups.get(i)); 
} 

for (PowerUp p : cpowerups) p.update(); 

한 가지를 묻는다면, 현재 목록이 수정되고 있는지를 탐지 할 수있는 방법이 있는가? 그리고 목록이 루프에서 벗어나도록 수정되고 있는지?

답변

0

ArrayList에서 요소를 제거하려면 루프에 Iterator을 사용해야합니다.

Iterator<PowerUp> iter = ((SurvivalMode) m).getPowerUps().iterator(); 
while(iter.hasNext()) { 
    PowerUp p = iter.next(); 
    // your conditions to remove element here 
    iter.remove(); 
} 
+0

해당 반복기에서 인덱스를 가져 오는 방법은 무엇입니까? 이것은 시도한 코드입니다 : \t'Iterator iter = ((SurvivalMode) m) .getPowerUps(). iterator(); \t while (iter.hasNext()) { \t \t PowerUp p = ((SurvivalMode) m) .getPowerUps(). get (???); \t \t if (iter.equals ((p))) iter.remove(); \t} – CoderMusgrove

+0

색인이 필요하지 않습니다. – Alex

+0

내가 그렇게 할 때, 실제로'if' 문 안에서 코드를 사용하지는 않는다; if (p.equals (hp)) iter.remove(); 나는 그것을 꺼내려고했는데 iter.remove();에서 IllegalStateException을 던졌습니다. – CoderMusgrove

0

전체 코드를 모르기 때문에 몇 가지 가정을해야합니다. 첫 번째 가정은 문제가되는 코드 조각이 PowerUp 클래스의 update 메서드에 의해 어떻게 든 호출된다는 것입니다.

[1]에서 설명한 것처럼 각 루프의 a는 Iterator 개체를 사용하여 ArrayList의 요소를 반복합니다.

ArrayList에 의해 반환 된 객체는 입니다. 패스트 패스트입니다. 즉, ArrayList이 객체 자체를 통하는 경우를 제외하고 어떤 형태로든 수정 된 경우 Iterator 객체를 수정하면 해당 메서드는 ConcurrentModificationException을 던집니다. (참조, [2])

내 가정이 맞다면, 당신의 코드 for (PowerUp p : powerups) p.update();이 같은 Iterator 객체를 생성하고 다른 특정의 코드 내에서 ArrayList을 수정합니다. Alex가 제안한 코드와 동일한 예외가 발생하는 이유가 여기에 있습니다. 당신이 Collection (ArrayList, LinkedList 등)을 반복 할 때마다

가 문제의 솔루션은, 복사본의 요소를 수집 및 반복의 단순 복사본을 생성하는 CopyOnWriteArrayList를 사용하는 것입니다 당신이 할 수 있도록 ConcurrentModificationException의 발생없이 원본 컬렉션을 수정하십시오. 의미 , 당신은 for (PowerUp p : CopyOnWriteArrayList(powerups) p.update();for (PowerUp p : powerups) p.update();을 교체하고 알렉스 제안한

Iterator<PowerUp> iter = ((SurvivalMode) m).getPowerUps().iterator(); 
while(iter.hasNext()) { 
    PowerUp p = iter.next(); 
    // your conditions to remove element here 
    iter.remove(); 
} 

을 사용해야합니다.

+0

'iter.remove()'는'CopyOnWriteArrayList' 클래스에서 사용할 수 없으며'UnsupportedOperationException'을 던집니다. – CoderMusgrove

+0

아, 죄송합니다. 문제가 무엇인지 알 겠어. 나는 그것을 분명히 밝히지 않았다. 그래서, 여기 내 교정 : 귀하의 요소를 반복, 귀하의 컬렉션 (귀하의 경우에는 요소를 삭제) 수정하려는 경우 **를 제외하고 ** CopyOnWriteArrayList를 ** 사용해야합니다. @Alex에서 제안한 원래 컬렉션을 사용해야합니다. – ojlr

+0

내 게시물을 업데이트했습니다.보세요. – CoderMusgrove

관련 문제