我正在尝试为大量玩家存储得分。所以我需要一个基于值排序的地图,但是由于每次我检索它时玩家的数量都很低。我也希望能够在地图中找到球员排名。它与redis中的score数据类型非常相似。 类似的东西:
ScoreMap<String, Integer> scores = new ScoreMap<String, Integer>();
scores.put("Bill", 2);
scores.put("Tom", 6);
scores.put("Jim", 3);
scores.put("Jake", 3);
System.out.println("Rank = " + scores.getRank("Bill"));
System.out.println();
System.out.println("All:");
for (Entry<String, Integer> entry : scores.entrySet()) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
System.out.println();
System.out.println("Rank Range:");
for (Entry<String, Integer> entry : scores.entryRankRange(0, 2)) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
System.out.println();
System.out.println("Score Range:");
for (Entry<String, Integer> entry : scores.entryScoreRange(2, 3)) {
System.out.println(entry.getKey() + " => " + entry.getValue());
}
这将返回
Rank = 3
All:
Tom => 6
Jake => 3
Jim => 3
Bill => 2
Rank Range:
Tom => 6
Jake => 3
Jim => 3
Score Range:
Jake => 3
Jim => 3
Bill => 2
我知道这有点具体,我可能需要制作自定义数据结构。但是,正确方向的一点将非常值得赞赏。 :)
答案 0 :(得分:2)
最简单的方法是使用Set
(即TreeSet
)并将玩家信息(包括得分)封装到特定的类中:
public class CompetitivePlayer implements Comparable<CompetitivePlayer>{
private String name;
private int score;
public CompetitivePlayer(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
public void incrementScore() {
score++;
}
@Override
public int compareTo(CompetitivePlayer o) {
return score - o.score;
}
}
TreeSet
假设存储在其中的entires实现Comparable
接口以确定其元素的自然顺序。
修改强>
如果您需要经常修改玩家的分数,那么基于Map<String, Integer>
的解决方案更适合,因为there's no get
in Java's Set
。 This thread详细讨论了基于Map
的方法。
一个简单的解决方案(如上面提到的主题所示)是一个单行,使用Guava库:
Map<String, Integer> sortedScores = ImmutableSortedMap.copyOf(scores,
Ordering.natural().onResultOf(Functions.forMap(scores)));
答案 1 :(得分:0)
使用Collections Runner
并提供自定义Comparator,根据地图对地图进行排序:
.sort()
答案 2 :(得分:0)
你可以重写你的名字和得分作为一个类玩家,然后你可以使用TreeSet保持顺序,并覆盖equals()和compareTo(),似乎你想使用名称作为标识符,并保持玩家有序按分数,然后就可以了
@Override
public boolean equals(Object obj) {
if(obj instanceof Player)
return this.name.equals(((Player)obj).name);
return false;
}
@Override
public int compareTo(Player p) {
return p.score - this.score;
}