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

时间:2016-02-06 19:20:12

标签: java android arraylist null-pointer

我正在用卡片,角色卡片制作游戏。

我首先创建用户选择的卡片,然后将它们添加到List,将其随机播放,然后逐个显示它们,并显示其玩家名称(由用户在之前的活动中选择)。

事实是,当我尝试从List中获取Card类并调用其方法时getPlayer()& getCharacter(返回播放器的名称和特定卡片的字符名称)我得到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>();
 }

}

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

这可能会让你发疯,但这是我发现实现角色创作的唯一方法(每个角色扩展了Card类!):

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

2 个答案:

答案 0 :(得分:1)

根据您的日志: characters.get(0)给出null并且在它上面你试图调用getCharacter()因此空指针异常。

检查字符大小为0或错误地将其分配给新对象。

最好的办法是对if(characters.size()&gt; 0)进行检查,然后才能从字符中获取。

你还没有初始化变量initializeVariables();永远不会被称为。

答案 1 :(得分:0)

来自我的other answer,您从中获取了我的代码。 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-check。 (而且我会把困扰的代码留在困扰我的地方)

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

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