按值排序的数据结构

时间:2015-05-30 23:02:40

标签: java data-structures

我正在尝试为大量玩家存储得分。所以我需要一个基于值排序的地图,但是由于每次我检索它时玩家的数量都很低。我也希望能够在地图中找到球员排名。它与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

我知道这有点具体,我可能需要制作自定义数据结构。但是,正确方向的一点将非常值得赞赏。 :)

3 个答案:

答案 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 SetThis 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;
}