2016-01-06 149 views
0

基本上,我正在MVC中制作一个yahtzee游戏。它工作正常,但是当我尝试保存游戏会话时,它不会保存包含玩家的游戏对象和阵列列表。这不会停止执行,这肯定会清除游戏的数组列表。 基本上,游戏的实例有以下字段:Java不能在Array列表中存储对象

public String name; 
public int numberOfPlayers; 
public ArrayList<Player> players = new ArrayList<>(); 
int playerListIndex; 
ArrayList<Boolean> checkable; 
StandardRules yahtzeeRule = new StandardRules(); 
public int rounds; 
public String date; 

球员ArrayList中包含有它自己的领域和gettters/setter方法的对象播放器的实例。

我已经成功地追踪问题不保存时,我调用的方法:

public void saveGame(Game thisGame) { 
    DB.saveGame(thisGame); 
} 

这反过来又调用类:

public class DB { 

private static ArrayList<Game> savedGames = new ArrayList<>(); 

/** 
* Saves the passed member into the database. 
* @param game, the member to be saved. 
*/ 
public static void saveGame(Game game) { 
    for (Game g : savedGames) { 
     if (g.name.equals(game.name)) { 
      savedGames.remove(g); 
      savedGames.add(game); 
     } 
     else { 
      savedGames.add(game); 
     } 
    } 
}  

游戏存档方法主要检查的数组列表如果名称已经存在,则保存游戏,如果它删除旧游戏并添加新游戏。如果没有这个名字的游戏,它只是将游戏添加到列表中。 (我可能稍后会实现MYSQL DB,但为了确保程序首先运行,我想用arraylist来测试)

我的印象是我需要一个静态参考数据库以确保我试图一直访问相同的数据库,而不是混淆数据库的实例。

我在这里做错了什么?

+0

看你的代码,我觉得HashMap的会比ArrayList好。每次不必迭代。 – Sunny

回答

2

试着按照逻辑。您正在循环阵列以保存游戏。如果数组是空的,你会期望发生什么?如果Array有六个元素,你会期望在这个列表中有什么?另外,如果这个循环会被列表中已经存在的名称执行,你很可能会遇到ConcurentModificationException。您可能想要遍历列表并将重复项存储到变量中。但是不要在循环中进行保存和删除。

那么,到底你的问题是,你遍历空列表,以保存Game,这实际上不会工作,因为你的List是空的,你永远也达不到,你讲一下你的List的部分。

您很有可能会选择这样的解决方案将游戏存储在您的List中。

public static void saveGame(Game game) { 
    Game dupGame = null; 
    for (Game g : savedGames) { 
     if (g.name.equals(game.name)) { 
      dupGame = g; 
     } 
    } 
    if (dupGame != null) { 
     savedGames.remove(dupGame); 
    } 
    savedGames.add(game); 
} 

编辑:

你也可以使用一个Map,这将使得寻找重复等有点更快,更容易。 becuas您从ArrayList读取和loop添加内容到它

public class DB { 

    private static Map<String,Game> savedGames = new HashMap<>(); 

    /** 
    * Saves the passed member into the database. 
    * 
    * @param game 
    *   , the member to be saved. 
    */ 
    public static void saveGame(Game game) { 
     savedGames.put(game.name.toLowerCase(), game); 
    } 
} 
+0

这解决了我的问题,我完全忘记了并发方面。谢啦! – Danny

0

找你方法可以返回一个例外。

试试这个。 :)

for(Game g : savedGames) { 
    if(g.name.equals(game.name)) { 
     savedGames.remove(g); 
     savedGames.add(0, game); 
    } else { 
     savedGames.add(0, game); 
    } 
} 
2

您希望将这些savedGames存储在内存中。将它们作为静态是没有问题的。你唯一的问题是你正在迭代savedGames列表,并修改它添加和删除几个游戏。这是错误的。它可能会给你并发更新异常。

public class DB { 

    private static ArrayList<Game> savedGames = new ArrayList<>(); 

    /** 
    * Saves the passed member into the database. 
    * @param game, the member to be saved. 
    */ 
    public static void saveGame(Game game) { 
      boolean exists=false; 
      boolean removalObject=null; 
      for (Game g : savedGames) { 
      if (g.name.equals(game.name)) { 
       exists=true; 
       removalObject=g; 
      } 
     } 
     savedGames.add(removalObject); 
     savedGames.add(game); 
    } 
} 
1

第一个问题是,试图将游戏添加到空的ArrayList,因为添加操作如果savedGames是空的,这将永远不会运行在循环中完成将失败。同样,如果Object类的equals(Object obj)在Game类中正确覆盖,则remove(Object obj)方法将按预期工作。 试试这个下面...... 覆盖在游戏中的等级等于()方法:

@Override 
public boolean equals(Object obj) { 
    if(obj != null && obj instanceof Game){ 
     Game gameObj = (Game)obj; 
     if(this.name.equals(gameObj.name)){ 
      return true; 
     } 
    } 
    return false; 
} 

执行秘技()方法如下:

public static void saveGame(Game g){ 
    if(games.contains(g)){ 
     games.remove(g); 
    } 
    // Add the game after removing the existing 
    // or if never existed 
     games.add(g); 
}