簡體   English   中英

Java無法將對象存儲在arraylist中

[英]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;

Player的Arraylist包含對象Player的實例,該對象具有自己的字段和getters / setters。

我設法在調用該方法時跟蹤到未保存的問題:

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 DB,但是為了確保程序首先運行,我想使用arraylist進行測試)

我的印象是,我需要對數據庫有一個靜態引用,以確保我一直在嘗試訪問同一數據庫,並且不會混淆數據庫的實例。

我在這里做錯了什么?

嘗試遵循邏輯。 您正在遍歷數組以保存游戲。 如果數組為空,您期望發生什么? 如果數組有六個元素,那么您希望該列表中包含什么? 此外,如果此循環將使用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);
    }
}

您想將這些saveGames保存在內存中。 將它們設為靜態沒有問題。 唯一的問題是您要遍歷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會失敗,因為添加操作是在循環內完成的,如果saveGames為空,它將永遠不會運行。 如果在Game類中正確重寫了Object類的equals(Object obj),則remove(Object obj)方法也會按預期工作。 請嘗試以下操作...覆蓋Game類中的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);
}

您的方法可以返回異常,因為您從ArrayList讀取了內容並在loop添加了內容。

嘗試這個。 :)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM