Java 无法在数组列表中存储对象
Java can't store Object in arraylist
基本上,我正在用 MVC 制作 yahtzee 游戏。它工作正常,但是当我尝试保存游戏会话时,它不会保存包含玩家数组列表的游戏对象。这不会停止执行,这肯定会清除游戏数组列表。
基本上,游戏实例具有以下字段:
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 包含对象 Player 的实例,它有自己的字段和 gettters/setters。
当我调用方法时,我设法跟踪到不保存的问题:
public void saveGame(Game thisGame) {
DB.saveGame(thisGame);
}
依次调用 class:
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 来测试东西)
我的印象是我需要对数据库进行静态引用,以确保我一直尝试访问同一个数据库,而不是混淆数据库的实例。
我做错了什么?
尝试遵循逻辑。您正在遍历数组以保存游戏。如果数组为空,您希望发生什么?如果 Array 有六个元素,你希望这个列表中有什么?此外,如果使用列表中已有的名称执行此循环,您很可能 运行 进入 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);
}
}
您的方法可以 return 异常,因为您从 ArrayList
中读取内容并在 loop
中添加内容。
试试这个。 :)
for(Game g : savedGames) {
if(g.name.equals(game.name)) {
savedGames.remove(g);
savedGames.add(0, game);
} else {
savedGames.add(0, game);
}
}
您想将这些已保存的游戏正确地保存在内存中。将它们设为静态没有问题。您遇到的唯一问题是您正在遍历 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);
}
}
第一个问题是,尝试将游戏添加到空的 ArrayList 将失败,因为添加操作是在循环内完成的,如果 savedGames 为空,则永远不会 运行。如果 Object class 的 equals(Object obj) 在游戏 class 中被正确覆盖,remove(Object obj) 方法也会按预期工作。
试试下面这个...
覆盖游戏中的 equal() 方法 Class:
@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);
}
基本上,我正在用 MVC 制作 yahtzee 游戏。它工作正常,但是当我尝试保存游戏会话时,它不会保存包含玩家数组列表的游戏对象。这不会停止执行,这肯定会清除游戏数组列表。 基本上,游戏实例具有以下字段:
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 包含对象 Player 的实例,它有自己的字段和 gettters/setters。
当我调用方法时,我设法跟踪到不保存的问题:
public void saveGame(Game thisGame) {
DB.saveGame(thisGame);
}
依次调用 class:
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 来测试东西)
我的印象是我需要对数据库进行静态引用,以确保我一直尝试访问同一个数据库,而不是混淆数据库的实例。
我做错了什么?
尝试遵循逻辑。您正在遍历数组以保存游戏。如果数组为空,您希望发生什么?如果 Array 有六个元素,你希望这个列表中有什么?此外,如果使用列表中已有的名称执行此循环,您很可能 运行 进入 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);
}
}
您的方法可以 return 异常,因为您从 ArrayList
中读取内容并在 loop
中添加内容。
试试这个。 :)
for(Game g : savedGames) {
if(g.name.equals(game.name)) {
savedGames.remove(g);
savedGames.add(0, game);
} else {
savedGames.add(0, game);
}
}
您想将这些已保存的游戏正确地保存在内存中。将它们设为静态没有问题。您遇到的唯一问题是您正在遍历 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);
}
}
第一个问题是,尝试将游戏添加到空的 ArrayList 将失败,因为添加操作是在循环内完成的,如果 savedGames 为空,则永远不会 运行。如果 Object class 的 equals(Object obj) 在游戏 class 中被正确覆盖,remove(Object obj) 方法也会按预期工作。 试试下面这个... 覆盖游戏中的 equal() 方法 Class:
@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);
}