I have a 2d array in Java 8:
String data[][] = new String[i][2];
And it looks like this:
Player1 8 Player5 3 Player3 9 Player4 5 ...
and I want to sort it to have the highest score at the top:
Player3 9 Player1 8 Player4 5 Player5 3
How can I sort this or is there a better way to do save this and sort it afterwards?
I already tried to search for solutions around here and only found this:
String[][] out = Arrays.stream(data).sorted(Comparator.comparing(x -> -Integer.parseInt(x[1]))).toArray(String[][]::new);
But this didn't work in my case
CodePudding user response:
Object-oriented design
Consider using object-oriented design, this means to have actual objects representing each player rather than rows in a 2D array. This is great coding practice since it increases readability and debuggability. It also helps the readers of your code to understand it better.
Something like this will do the trick:
class Player {
String name;
int score;
}
This allows you to create many instances of "Player", each of which have their own names (for example "player1", or any other text), and their own score.
While this is better, it can still be improved by making the name of players final
. This means it cannot be changed once it is assigned in the constructor:
class Player {
final String name; // we made this final
int score;
Player(String name) { // this is the constructor
this.name = name;
}
}
Another way we can improve our code is by making the fields private
, which means their value can only be changed in the way we allow it.
class Player {
private final String name; // we made this
private int score; // and this, private
Player(String name) {
this.name = name;
}
public int getScore() { // so we need a getter
return score;
}
public void setScore(int score) { // and a setter, for score
this.score = score;
}
public String getName() { // we also need a getter for name
return name; // but no setter, because it is final
}
}
Using this technique, you can set limits for score, for example not allowing to be negative, or more than 1000. Or you can omit the setter and instead have an addScore
method that only allows increasing the score of a player.
After we have our class, we can create however many players we want, like this:
Player p1 = new Player("player1");
And then we can access its methods like setting and getting score like this:
int s = p1.getScore();
p1.setScore(s*2); // doubles the score of player1
Sorting
To be able to sort objects in arbitrary ways, we would need to put them in data structures or "collections", like lists. You had used an array which is a very primitive data structure whose length cannot be increased or decreased once it is created.
To put your players in a list, simply create a list and add
them to it like this:
List<Player> players = new ArrayList<>();
players.add(p1);
After you have added all your players into a list, you can sort the players in the list based on their score, like this:
players.sort(Comparator.comparingInt(Player::getScore))
You can even sort them by their names if you want:
players.sort(Comparator.comparing(Player::getName));
If you want to learn what that ::
symbol means, read more about "method reference".