Osama Benrottihalen
Osama Benrottihalen

Reputation: 63

Why is the length of my arraylist generated by a for loop always zero (Java)?

First of all, thank you for taking the time to read this. I am quite new to android development and appreciate all the help I can get. I'll keep the description brief.

I'm developing an app as a side project to speed up the d&d sessions of me and my friends by automating the initiative rolls (rolling a 20-sided dice, adding a personal modifier and sorting from largest to smallest). Everything was going great until I hit a bug which to my frustration I haven't been able to fix. The length of the sorted Arraylist with names and of the complimentary dictionary always seems to be zero and I cannot find out why. Code is posted below.

First step is to collect user data from the input. the input works like this (this explains the weird ID's)

enter image description here

//updates player database with user input
private void updateDictionaryManager(int _partySize) {
    listManager.empty();

    if (_partySize > 0) {
        for (int i = 0; i < _partySize + 1; i++) {
            EditText Name = (EditText)findViewById(i);
            EditText dexMod = (EditText)findViewById(i + 10);
            String playerName = "player " + String.valueOf(i);
            int playerDexMod = 0;

            if (Name.getText() != null) {
                playerName = Name.getText().toString();
            }

            if (dexMod.getText() != null) {
                try {
                    playerDexMod = Integer.parseInt(dexMod.getText().toString());
                } catch (Exception e) {
                    playerDexMod = 0;
                }
            }
            listManager.append(playerName, playerDexMod, i);
        }
    }
}

This is the code from the listmanager class

public void append(String _name, int _dexMod, int _playerNumber) {
    if (!_name.equals("")) {
        playerNames.add(_name);
    } else {
        String defaultName = "player " + String.valueOf(_playerNumber);
        playerNames.add(defaultName);
    }
    dexMod.add(_dexMod);
}

public void empty() {
    playerNames.clear();
    dexMod.clear();
}

I guess the problem hides here (but I send the prvious just in case I missed something there)

final class InitiativeRoller extends ListManager{
Map<Integer, List<String>> playerRolls = new HashMap<>();
Map<String, Integer> outputDictionary = new HashMap<>();

List<Integer> alreadyRolled = new ArrayList<>();
List<String> outputOrder = new ArrayList<>();

public void roll() {
    //retrieve lists from manager
    List<String> _names = getPlayerNames();
    List<Integer> _dexMod = getDexMod();

    //rolling the dice and saving values
    for (int i = 0; i < getSize(); i++) {
        int _roll = (int) Math.round(Math.random() * 19) + 1 + _dexMod.get(i);

        if (alreadyRolled.contains(_roll)) {
            //add name to list in dictionary with corresponding roll
            playerRolls.get(_roll).add(_names.get(i));
        } else {
            //generate new list for players with this roll and add to playerRolls
            List<String> _list = new ArrayList<>();
            _list.add(_names.get(i));
            playerRolls.put(_roll, _list);

            alreadyRolled.add(_roll);
        }
    }

    //sorting the rolls from largest to smallest
    Collections.sort(alreadyRolled);
    Collections.reverse(alreadyRolled);

    //generating output dictionary
    for (int i = 0; i < alreadyRolled.size(); i++) {
        int _roll = alreadyRolled.get(i);
        List<String> list = playerRolls.get(_roll);

        //shuffling order of players with the same roll
        Collections.shuffle(list);

        //add to output dictionary and list
        for (int x = 0; x < list.size(); x++) {
            outputDictionary.put(list.get(x), _roll);
            outputOrder.add(list.get(x));
        }
    }
}

public Map<String, Integer> getOutputDictionary() {
    return outputDictionary;
}

public List<String> getOutputOrder() {
    return outputOrder;
}

}

Every time I check, the resulting outputDictionary and outputorder have a length of zero. What am I missing? Sorry for the long post.

EDIT: I have checked the code and there does not seem to be a problem with the length of the list until the point where getPlayerNames and getDexMod are called inside the InitiativeRollerClass.

EDIT: Here are the get-methods

public List<String> getPlayerNames() {
    return playerNames;
}

public List<Integer> getDexMod() {
    return dexMod;
}

UPDATE: This is the code bound to the roll-button:

rollInitiative.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //update dictionary
            int roundedProgress = Math.round(playerSlider.getProgress());

            try {
                updateDictionaryManager(roundedProgress);
            } catch (Exception e) {
                updateDictionaryManagerOnException(roundedProgress, playerList);
            }

            initiativeRoller.roll();
            displayResult(initiativeRoller.getOutputOrder(), initiativeRoller.getOutputDictionary(), InitiativeList);
        }
    });

the method is described here, this is just for debugging

//displays output to user
    private void displayResult(List<String> _outputOrder, Map<String, Integer> _outputDictionary, TextView _initiativelist) {
        _initiativelist.setText(listManager.getDexMod() + "\n" + listManager.getPlayerNames()
        + "\n" + initiativeRoller.getOutputOrder());
    }

This brings me the following

enter image description here

I also checked online if the code itself for the roll class was even functioning, it was. Here is the result for four hard coded names and values after a number of runs:

[Aaron, Josh, Clide, Li]
{Aaron=24, Clide=20, Josh=22, Li=8}
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
[Josh, Li, Aaron, Clide]
{Aaron=6, Clide=6, Josh=20, Li=12}
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
[Aaron, Clide, Li, Josh]
{Aaron=20, Clide=17, Josh=10, Li=11}
sh-4.3$ java -Xmx128M -Xms16M HelloWorld
[Li, Aaron, Clide, Josh]
{Aaron=19, Clide=18, Josh=18, Li=21}

Everything seems to be working just fine, I just don't understand why the returned list has a length of zero.

p.s. the code for the getSize() method

public int getSize() {
    return playerNames.size();
}

Upvotes: 1

Views: 178

Answers (1)

Nicola36631
Nicola36631

Reputation: 74

Ok, this might be the error: keep in mind that in Java every variable just as any other compiled language has a scope. Now you decleare playerName and playerDexMod inside the for and you append them inside that for, up until now everything is in check. When you exit the for however those variables just die, and by that I mean that the java garbage collector, since they're out of scope, should deallocate them. Now the listManager ( which I suppose is an ArrayList) finds itself with objects that don't exist anymore, so basically null. And that's just an empty array list. If the listManager you use is decleared in a class try to decleare also the other variables in a class, so they won't get out of scope. Tell me if this helps.

Upvotes: 1

Related Questions