2016-11-28 1 views
-2

Java를 사용하여 온라인 비디오 게임을 만들고 있습니다. 클라이언트 및 서버 응용 프로그램이있는 경우. 서버에서 플레이어 데이터베이스를 처리하기 위해 플레이어 개체 (InetAdress ipAdress 및 String username 포함)가 들어있는 inGamePlayers라는 ArrayList를 만듭니다.Java ConcurrentModificationException (ArrayList 포함)

플레이어가 연결되면 먼저 연결 플레이어 사용자 이름 ==가 ArrayList 사용자 이름의 플레이어 중 하나에 있는지 확인합니다. 그렇지 않은 경우 목록에 추가합니다. 그렇지 않으면 연결 한 플레이어가 '다시 연결'된 것으로 간주됩니다 ...

Eclipse에서 실행되면 이상하게 작동합니다. 그래서 저는 "Java Tutor"(코드를 읽고 변수를 보여주는 웹 사이트인데 프로그래밍을 시작할 때 정말 편리합니다)에서 코드의 일부를 테스트하기로 결정했습니다. 제

for (Player p : inGamePlayers) { 

라인에서

, 그것은 java.util.ConcurrentModificationException 정지하고, 제하지만 바이 패스 번째 생략했다.

여기

import java.util.ArrayList; 

public class YourClassNameHere { 

    public static void main(String[] args) { 

     ArrayList<Player> inGamePlayers = new ArrayList<Player>(); 
     inGamePlayers.add(new Player("Griff")); 

     String newUsername = "Polak"; 

     for (Player p : inGamePlayers) { 

      if (newUsername == p.username) { 
       System.out.println(p.username+" reconnected!"); 
       break; 
      } 

      inGamePlayers.add(new Player(newUsername)); 
     } 

     for (Player p : inGamePlayers) { 
      System.out.println(p.username); 
     } 
    } 
} 

class Player { 

    public String username; 

    public Player(String username) { 
     this.username = username; 
    } 
} 
+2

당신이 전체'for' 루프를 게시하시기 바랍니다 수 :

for (Player p : inGamePlayers) { if (newUsername == p.username) { // This needs to be .equals System.out.println(p.username+" reconnected!"); break; } // this line runs many times inGamePlayers.add(new Player(newUsername)); } 

대신 나는 당신이 새로운 기능에 그 코드를 추출하고, 제어 흐름을 변경하는 것이 좋습니다. 분명히 오류는 그 라인에서만 오는 것은 아닙니다. – Mat

+0

반복하는 동안 콜렉션을 수정하면 일반 콜렉션에 대한 반복이'ConcurrentModificationException'으로 폭발합니다. 간단한 수정 :'Set' ('HashSet'처럼)을 사용하고 체크하지 않고 add 만하면 - 세트는 중복이 없음을 보장합니다. 이 "통찰력"은 모두 javadoc에서 사용할 수 있습니다. – Bohemian

+0

@ ΦXocę 웃 Пepeúpa ツ OP는 다중 스레드를 필요로하지 않습니다. AFAICT 그가 루프 내부에 추가 중입니다 – Bohemian

답변

3

이 코드는 여러 결함을 가지고 내 전체 테스트 코드입니다. 이 양식에서는 이름이 일치하는 항목이 발견 될 때까지 새 Player 인스턴스를 추가합니다. 반복을 시작하고, 목록을 수정하고, 반복을 계속하면 관찰 한대로 ConcurrentModificationException을 던집니다. 또한 equals 대신 ==으로 문자열을 비교합니다.

private static void handleConnected(ArrayList<Player> inGamePlayers, String newUsername) { 
    for (Player p : inGamePlayers) { 
    if (newUsername.equals(p.username)) { 
     System.out.println(p.username+" reconnected!"); 
     return; // return instead of break 
    } 
    } 
    // we did not return, so this user is new 
    inGamePlayers.add(new Player(newUsername)); 
} 

// ... 

public static void main(String[] args) { 
    ArrayList<Player> inGamePlayers = new ArrayList<Player>(); 
    inGamePlayers.add(new Player("Griff")); 

    String newUsername = "Polak"; 

    // Call this function in place of the old loop 
    handleConnected(inGamePlayers, newUsername); 

    for (Player p : inGamePlayers) { 
    System.out.println(p.username); 
    } 
} 
+0

대담한 솔루션을 제공해 주셔서 감사합니다! @PravinSonawane 맞아, 그것을 통해 반복하면서 내 ArrayList 수정할 수 없다 – GriffinBabe

관련 문제