我正在使用Java创建在线视频游戏。 如果有客户端和服务器应用程序。 在服务器中,为了处理播放器数据库,我创建了一个名为inGamePlayers的ArrayList,它包含Players对象(使用InetAdress ipAdress和String username)。
当播放器连接时,它首先检查连接播放器用户名==是否为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;
}
}
答案 0 :(得分:3)
此代码有多个缺陷。在这种形式中,它将添加新的Player实例,直到找到具有匹配名称的条目。开始迭代,修改列表并继续迭代将抛出ConcurrentModificationException
。此外,您将字符串与==
进行比较,而不是equals
。
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));
}
相反,我建议您将该代码提取到新函数,并更改控制流程:
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);
}
}