在第一列中按整数对二维字符串数组进行排序
Sort 2d String array by integer in first column
我在 Java 8 中有一个二维数组:
String data[][] = new String[i][2];
它看起来像这样:
Player1 8 Player5 3 Player3 9 Player4 5 ...
我想对它进行排序,使其得分最高:
Player3 9 Player1 8 Player4 5 Player5 3
我该如何对它进行排序,或者是否有更好的方法来保存它并在之后对其进行排序?
我已经尝试在这里搜索解决方案,但只找到了这个:
String[][] out = Arrays.stream(data).sorted(Comparator.comparing(x -> -Integer.parseInt(x[1]))).toArray(String[][]::new);
但这对我不起作用
Object-oriented设计
考虑使用 object-oriented 设计,这意味着用实际对象代表每个玩家,而不是二维数组中的行。这是很好的编码实践,因为它提高了可读性和可调试性。它还可以帮助您的代码的读者更好地理解它。
像这样的东西就可以了:
class Player {
String name;
int score;
}
这允许您创建许多“玩家”实例,每个实例都有自己的名称(例如“玩家 1”或任何其他文本)和自己的分数。
虽然这样更好,但仍然可以通过制作玩家的名字来改进final
。这意味着一旦在构造函数中分配它就不能更改:
class Player {
final String name; // we made this final
int score;
Player(String name) { // this is the constructor
this.name = name;
}
}
我们可以改进代码的另一种方法是制作字段 private
,这意味着它们的值只能以我们允许的方式更改。
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
}
}
使用此技术,您可以设置分数限制,例如不允许为负数或超过 1000。或者您可以省略 setter 并使用 addScore
方法只允许增加玩家的分数。
在我们有了 class 之后,我们可以创建任意数量的玩家,像这样:
Player p1 = new Player("player1");
然后我们可以像这样访问它的设置和获取分数的方法:
int s = p1.getScore();
p1.setScore(s*2); // doubles the score of player1
正在排序
为了能够以任意方式对对象进行排序,我们需要将它们放入数据结构或“集合”中,例如列表。您使用的数组是一种非常原始的数据结构,其长度一旦创建就不能增加或减少。
要将您的玩家放入列表中,只需创建一个列表并 add
他们像这样:
List<Player> players = new ArrayList<>();
players.add(p1);
将所有玩家添加到列表后,您可以根据得分对列表中的玩家进行排序,如下所示:
players.sort(Comparator.comparingInt(Player::getScore))
如果需要,您甚至可以按名称对它们进行排序:
players.sort(Comparator.comparing(Player::getName));
如果您想了解 ::
符号的含义,请阅读有关“方法参考”的更多信息。
我在 Java 8 中有一个二维数组:
String data[][] = new String[i][2];
它看起来像这样:
Player1 8 Player5 3 Player3 9 Player4 5 ...
我想对它进行排序,使其得分最高:
Player3 9 Player1 8 Player4 5 Player5 3
我该如何对它进行排序,或者是否有更好的方法来保存它并在之后对其进行排序?
我已经尝试在这里搜索解决方案,但只找到了这个:
String[][] out = Arrays.stream(data).sorted(Comparator.comparing(x -> -Integer.parseInt(x[1]))).toArray(String[][]::new);
但这对我不起作用
Object-oriented设计
考虑使用 object-oriented 设计,这意味着用实际对象代表每个玩家,而不是二维数组中的行。这是很好的编码实践,因为它提高了可读性和可调试性。它还可以帮助您的代码的读者更好地理解它。
像这样的东西就可以了:
class Player {
String name;
int score;
}
这允许您创建许多“玩家”实例,每个实例都有自己的名称(例如“玩家 1”或任何其他文本)和自己的分数。
虽然这样更好,但仍然可以通过制作玩家的名字来改进final
。这意味着一旦在构造函数中分配它就不能更改:
class Player {
final String name; // we made this final
int score;
Player(String name) { // this is the constructor
this.name = name;
}
}
我们可以改进代码的另一种方法是制作字段 private
,这意味着它们的值只能以我们允许的方式更改。
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
}
}
使用此技术,您可以设置分数限制,例如不允许为负数或超过 1000。或者您可以省略 setter 并使用 addScore
方法只允许增加玩家的分数。
在我们有了 class 之后,我们可以创建任意数量的玩家,像这样:
Player p1 = new Player("player1");
然后我们可以像这样访问它的设置和获取分数的方法:
int s = p1.getScore();
p1.setScore(s*2); // doubles the score of player1
正在排序
为了能够以任意方式对对象进行排序,我们需要将它们放入数据结构或“集合”中,例如列表。您使用的数组是一种非常原始的数据结构,其长度一旦创建就不能增加或减少。
要将您的玩家放入列表中,只需创建一个列表并 add
他们像这样:
List<Player> players = new ArrayList<>();
players.add(p1);
将所有玩家添加到列表后,您可以根据得分对列表中的玩家进行排序,如下所示:
players.sort(Comparator.comparingInt(Player::getScore))
如果需要,您甚至可以按名称对它们进行排序:
players.sort(Comparator.comparing(Player::getName));
如果您想了解 ::
符号的含义,请阅读有关“方法参考”的更多信息。