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

lionbear28
  • 23
  • 8

3 Answers3

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()]);
});
Modus Tollens
  • 5,083
  • 3
  • 38
  • 46
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; 
}
David Conrad
  • 15,432
  • 2
  • 42
  • 54
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.

Matthew Brzezinski
  • 1,685
  • 4
  • 29
  • 53
  • You should declare the type as `List>`; code to the interface, not to the implementation. Also, your first loop won't work; `retVal.get` will fail since the list is empty. – David Conrad Dec 12 '16 at 21:03
  • 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. – Matthew Brzezinski Dec 12 '16 at 21:07
  • 1
    It's very common advice and important if you might ever switch to another implementation (say, a `LinkedList`). See [this question](http://stackoverflow.com/questions/383947/what-does-it-mean-to-program-to-an-interface) for more information. – David Conrad Dec 12 '16 at 21:41