0

So I'm trying to go through an arraylist of objects that all have a certain strength value and depending on their strength value, they go into the bigger 2d array based on that. So if their strength value is 0 then they go in the 0th array of the bigger one and this is what my code looks like so far

private ArrayList<Battleable> arr;


public BattleDeck() {
    arr = new ArrayList<Battleable>(); 
    for (Battleable creature: arr){ 
        arr.add(creature); 
    }

}

public Battleable[][] export2Darray() { 
    //returns a two-dimensional ragged array where each row  
    //  contains a deep copy of all of the Battleable objects 
    //  in the BattleStack with the corresponding Level value 
    Battleable[][] retVal = new Battleable[10][]; 


    int k = 0; 

    for (int i = 0; i<arr.size(); i++){ 
        int levelOfObj = arr.get(i).getLevel();  
        if(levelOfObj == k) {
            //insert it into retVal[0][0]

        }

        }
    }

    return retVal; 
} 

and I was wondering how I would do that? How do i syntax-tically say "get the obj that has strength 0 and put it in position 0 0 of my 2d array

9
  • 1
    You forgot to ask a question. Commented Dec 12, 2016 at 19:22
  • oops! I've fixed it. Commented Dec 12, 2016 at 19:26
  • 1
    Also could you include what arr is? Commented Dec 12, 2016 at 19:28
  • 1
    Arrays are fixed size. You want lists. If you really need them as arrays, you can convert the lists to arrays after using them to accumulate the Battleables. Commented Dec 12, 2016 at 19:32
  • 1
    I added an answer with an example of what I mean. Let me know if it's not clear. (Note: It might be easier to just keep the data in a map from level to list of item, rather than a two-dimensional array.) Commented Dec 12, 2016 at 22:07

3 Answers 3

1

A solution using Java 8 streams:

// group Battleables ArrayList by strength
Map<Integer, List<Battleable>> map = 
    arr.stream().collect(Collectors.groupingBy(Battleable::getStrength));

The result is a Map containing the Battleables as Lists with their strength as their key.

If you need the result as a jagged 2D array, sort the entries like this:

final Battleable[][] arrays = new Battleable[10][];
map.entrySet().forEach(entry -> {
    arrays[entry.getKey()] = entry.getValue().toArray(new Battleable[entry.getValue().size()]);
});
Sign up to request clarification or add additional context in comments.

Comments

1

Since arrays are of fixed size in Java, there is no clean way to add items to an array. You can resize the array each time by creating a new array each time, one larger than the last, and copying the data from the old array to the new array, but that would be messy and you would be reinventing a wheel called ArrayList. Modus Tollens has a good answer, but it uses some slightly advanced Java 8 concepts. Here's one way to write it without them:

public Battleable[][] export2Darray() { 
    Battleable[][] retVal = new Battleable[10][];

    // create a map that will hold the items, arranged by level
    Map<Integer, List<Battleable>> byLevel = new HashMap<>();
    for (int i = 0; i < 10; i++) {
        // initialize all levels with empty lists
        byLevel.put(i, new ArrayList<>());
    }

    for (Battleable battleable : arr) { 
        int level = battleable.getLevel();
        // get the list for this level and add to it
        byLevel.get(level).add(battleable);
    }

    // Now we have a map from levels to lists of battleables;
    // we need to turn each list into an array in our retVal

    for (int level = 0; level < 10; level++) {
        // get each list, convert it toArray and assign to slot in retVal
        retVal[level] = byLevel.get(level).toArray(new Battleable[0]);
    }

    return retVal; 
}

Comments

0

Here's a solution using ArrayLists, I am creating an ArrayList which will be referenced by strength, then inside of this I have another ArrayListwhich will have all of the Battleable objects of that strength level.

public ArrayList<ArrayList<Battleable>> exportBattleable() { 
    ArrayList<ArrayList<Battleable>> retVal = new ArrayList<ArrayList<Battleable>>();

    for (int i = 0; i < arr.size(); i++){
        retVal.get(arr.getLevel()).add(arr.get(i));
    }
    return retVal; 
}

Now if you want to print all Battleable objects of strength = 3, you would do:

ArrayList<Battleable> strength3 = retVal.get(3);
for(Battleable battleable : strength3) {
    System.out.println(battleable.toString());
}

This way you don't have to worry about re-sizing your arrays depending on how many Battleable objects you are adding in, same with strength levels, if you decide that instead of using strength levels from 0-9 that you wanted to use 0-20 you already have the ability to scale up or down.

3 Comments

You should declare the type as List<List<Battleable>>; code to the interface, not to the implementation. Also, your first loop won't work; retVal.get will fail since the list is empty.
That's true, I assume that OP keeps a strength level somewhere, all you'd need to do is loop through retVal and instantiate it to that many Lists. Any particular reason for using the interface and not the implementation? I wasn't able to find anything about this.
It's very common advice and important if you might ever switch to another implementation (say, a LinkedList). See this question for more information.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.