基本上,我在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来测试事物)
我的印象是我需要对数据库进行静态引用,以确保我一直试图访问同一个数据库,而不是混淆数据库的实例。
我在这里做错了什么?
答案 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}}