如何在 ArrayList 中存储自定义对象

How to store custom objects in an ArrayList

我正在用卡片、人物卡片制作游戏。

我首先创建用户选择的卡片,然后将它们添加到 List,洗牌,然后一张一张地显示它们,以及他们的玩家名称(在之前的 activity 由用户)。

事实是,当我尝试从列表中获取卡片 class 并调用其方法 getPlayer() 和 getCharacter(其中 return 玩家姓名和角色姓名特定卡的)我得到 nullPointer 异常。

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.leonardo.lupusintabula.characters.Card.getCharacter()' on a null object reference

randomButton.setText(characters.get(0).getCharacter() + " / " + characters.get(0).getPlayer());

onCreate():

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_random_assignment);

    //Retrieving
      ...
    //Done retrieving
    initializeVariables();
    createCharacters();
    run();
}

由于问题可能出在字符上,我列出了其中的所有代码:

// Where the characters are stored
private ArrayList<Card> characters;


public void initDeck() {
    addCharacter(demoniac, demoniacAmount, characters);
    addCharacter(guard, guardAmount, characters);
    addCharacter(medium, mediumAmount, characters);
    addCharacter(mythomaniac, mythomaniacAmount, characters);
    addCharacter(owl, owlAmount, characters);
    addCharacter(werehamster, werehamsterAmount, characters);
    addCharacter(getVillagerBundle(), villagerAmount, characters);
    addCharacter(masonOne, 1, characters);
    addCharacter(masonTwo, 1, characters);
}

public void addCharacter(Card card, int amount, List<Card> cards) {
    if (amount < 0) {
        throw new IllegalArgumentException("Must add a non-negative number of characters for " + card.getCharacter() );
    }

    for (int i = 0; i < amount; i++) {
        cards.add(card);
    }
}



//Pick a random one and display it
public void pick(View view){
    if(characters != null) {
        if (i < characters.size()) {
            randomButton.setText(characters.get(i).getCharacter() + " / " + characters.get(i).getPlayer());
            i++;
        } else {
            randomButton.setText(R.string.play);
        }
    }
}

void run() {
    // initialize the characters
    initDeck();

    // shuffle them
    Collections.shuffle(characters);

    //Display the 1st card
    if(characters != null) {
        randomButton.setText(characters.get(0).getCharacter() + " / " + characters.get(0).getPlayer());
    }
}


private void initializeVariables() {
    ...
    ...

    characters = new ArrayList<Card>();
 }

}

我做错了什么?如果您需要其他部分代码,请随时询问,我会尽快提供给您!

这可能会让你发疯,但这是我找到的实现角色创建的唯一方法(每个角色都会扩展卡片class!):

public void createCharacters() {
    if (demoniacAmount != 0) {
        demoniac = new Demoniac(nameList.get(listIndex));
        listIndex++;
    } else if (guardAmount != 0) {
        guard = new Guard(nameList.get(listIndex));
        listIndex++;
    } else if (mediumAmount != 0) {
        medium = new Medium(nameList.get(listIndex));
        listIndex++;
    } else if (mythomaniacAmount != 0) {
        mythomaniac = new Mythomaniac(nameList.get(listIndex));
        listIndex++;
    } else if (owlAmount != 0) {
        owl = new Owl(nameList.get(listIndex));
        listIndex++;
    } else if (werehamsterAmount != 0) {
        werehamster = new Werehamster(nameList.get(listIndex));
        listIndex++;
    } else if (masonsAmount != 0) {
        masonOne = new Masons(nameList.get(listIndex));
        masonTwo = new Masons(nameList.get(listIndex));
        listIndex += masonsAmount;
    } else if (villagerAmount > 5) {
            villagerSix = new Villager(nameList.get(listIndex));
            villagerBundle.add(villagerSix);

            if (villagerAmount > 6) {
                villagerSeven = new Villager(nameList.get(listIndex));
                villagerBundle.add(villagerSeven);

                if (villagerAmount > 7) {
                    villagerEight = new Villager(nameList.get(listIndex));
                    villagerBundle.add(villagerEight);

                    if (villagerAmount > 8) {
                        villagerNine = new Villager(nameList.get(listIndex));
                        villagerBundle.add(villagerNine);

                        if (villagerAmount > 9) {
                            villagerTen = new Villager(nameList.get(listIndex));
                            villagerBundle.add(villagerTen);

                            if (villagerAmount > 10) {
                                villagerEleven = new Villager(nameList.get(listIndex));
                                villagerBundle.add(villagerEleven);

                                if (villagerAmount > 11) {
                                    villagerTwelve = new Villager(nameList.get(listIndex));
                                    villagerBundle.add(villagerTwelve);

                                    Toast.makeText(RandomAssignment.this, "works", Toast.LENGTH_SHORT).show();
                                }
                            }
                        }
                    }
                }
            }
        }
        listIndex += villagerAmount;
    }

根据您的日志: characters.get(0) 给出 null 并且您正在尝试调用 getCharacter() 因此出现空指针异常。

检查您的字符大小在哪里变为 0,或者您错误地将其分配给了一个新对象。

最好的方法是应用检查 if(characters.size() > 0) 那么只有你从字符中得到。

您还没有初始化变量initializeVariables();从未被调用。

来自我的 ,你从中获取了我的代码。 initDeck 方法实际上是这样读的

public void initDeck() {
    if (characters == null)
        characters = new ArrayList<String>();

        // addCharacter...

这至少会避免列表中出现空指针...


您需要为您的问题添加更多代码,但问题开始于此块

addCharacter(demoniac, demoniacAmount, characters);
addCharacter(guard, guardAmount, characters);
addCharacter(medium, mediumAmount, characters);
addCharacter(mythomaniac, mythomaniacAmount, characters);
addCharacter(owl, owlAmount, characters);
addCharacter(werehamster, werehamsterAmount, characters);
addCharacter(getVillagerBundle(), villagerAmount, characters);
addCharacter(masonOne, 1, characters);
addCharacter(masonTwo, 1, characters);

哪个(大致)调用此代码

public void addCharacter(Card card, int amount, List<Card> cards) {
    for (int i = 0; i < amount; i++) {
        cards.add(card);
    }
}

问题是某处这些变量中的任何一个都是空的,它们被添加到列表中

  • demoniac
  • guard
  • medium
  • mythomaniac
  • owl
  • werehamster
  • getVillagerBundle()
  • masonOne
  • masonTwo

您可以通过将所有这些变量分配给 new Card() 来解决这个问题,或者像这样避免问题

public void addCharacter(Card card, int amount, List<Card> cards) {
    for (int i = 0; i < amount; i++) {
        if (card != null) {
            cards.add(card);
        } else {
            Log.e("addCharacter", "Hey! Are you sure you meant to add a null card?");
        }
    }
}

现在你展示了更多的代码,错误从这里开始

if (demoniacAmount != 0) {
    demoniac = new Demoniac(nameList.get(listIndex));
    listIndex++;
} else if (guardAmount != 0) {
    guard = new Guard(nameList.get(listIndex));
    listIndex++;
}

如果 demoniacAmountguardAmount 都不为零怎么办,嗯?只有第一个 if 条件才会被输入。 guard 最终会变成 null,因为它从未被初始化。对完全不同的变量做 else-if 是没有意义的!

像这样针对所有这些条件正确执行您的 if 检查。 (我会尽可能多地留下混乱的代码)

if (demoniacAmount != 0) {
    demoniac = new Demoniac(nameList.get(listIndex));
    listIndex++;
} 

if (guardAmount != 0) {
    guard = new Guard(nameList.get(listIndex));
    listIndex++;
}