Java无法在arraylist

时间:2016-01-06 13:38:23

标签: java database arraylist storing-data

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

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);
        }
    }
}    

如果名称已存在,saveGame方法基本上会检查已保存游戏的Arraylist,如果已存在,则删除旧游戏并添加新游戏。如果没有该名称的游戏,它只是将游戏添加到列表中。 (我可能稍后会实现一个MYSQL数据库,但是为了确保程序首先运行,我想使用arraylist来测试事物)

我的印象是我需要对数据库进行静态引用,以确保我一直试图访问同一个数据库,而不是混淆数据库的实例。

我在这里做错了什么?

4 个答案:

答案 0 :(得分:2)

尝试遵循逻辑。您正在循环数组以保存游戏。如果数组是空的,你会发生什么?如果Array有六个元素,你期望在这个列表中有什么?此外,如果使用已在List中的名称执行此循环,则很可能会遇到ConcurentModificationException。您可能希望遍历List并将副本存储到变量中。但是不要在循环中进行保存和删除。

所以最后你的问题是你在循环空列表以保存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,这样可以更快,更轻松地查找副本等等。

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);
    }
}

答案 1 :(得分:2)

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

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);
    }
}

答案 2 :(得分:1)

第一个问题是,尝试将游戏添加到空ArrayList会失败,因为添加操作是在循环内完成的,如果savedGames为空,它将永远不会运行。如果Object类的equals(Object obj)在Game类中正确覆盖,remove(Object obj)方法也可按预期工作。 试试以下...... 覆盖Game Class中的equal()方法:

@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;
}

执行saveGame()方法如下:

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);
}

答案 3 :(得分:0)

您的方法可以返回一个例外,因为您从for(Game g : savedGames) { if(g.name.equals(game.name)) { savedGames.remove(g); savedGames.add(0, game); } else { savedGames.add(0, game); } } 读取并在{{1}}中向其添加内容。

试试这个。 :)

{{1}}