我正在尝试为大部分玩家存储分数。因此,我将需要根据值排序的地图,但是由于玩家数量众多,每次检索时对它进行排序的效率都很低。我还希望能够在地图上找到球员排名。它与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
我知道这是特定的,我可能必须创建一个自定义的数据结构。但是,朝着正确方向的观点将不胜感激。 :)
最佳答案
最简单的方法是使用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
假定存储在其中的整体实现了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)));