按最高分数排序地图

时间:2014-06-24 17:15:48

标签: java

我有一张存储球员姓名的地图,以及我更新和得分的分数。

public static Map<String, Integer> map = new HashMap<String, Integer>();

在我的第一轮比赛结束后,我想从地图中删除最低分数。例如,地图中可能有8个玩家,其中4个得分为10,另外4个得分为0,我如何根据最佳得分手将地图分成两半并删除底部4?请记住,未定义8个玩家,可以是任意数字

4 个答案:

答案 0 :(得分:1)

似乎没有人认识到这不是一个映射。如果你看高分,名字可以是重复的。你想要的是一个NavigableSet,其中<​​/ p>

class HighScore implements Comparable<HighScore> {
    private static final AtomicLong NEXT_ID = new AtomicLong(1);

    protected final String name;
    protected final long id = NEXT_ID.getAndIncrement();
    protected final int score;

    // ...

    public int compareTo(HighScore o) {
        int diff = score - o.score;
        if (diff != 0) { return diff; }

        long idDiff = id - o.id;
        if (idDiff < 0) { return -1; }
        else if (idDiff > 0) { return 1; }
        else { return 0; }
    }
}

然后你可以pollFirst()删除。

答案 1 :(得分:1)

以下是可能对您有所帮助的内容。我使用相同的键和值值填充了Map,以便在打印时查看顺序。以下示例包括

  • 获取上半部视图而不从原始地图中删除下半部分的方法
  • 并从原始地图中移除下半部分。

除非要求删除不需要删除下半部分,否则仍然得到原始地图支持的headMap。

import java.util.NavigableMap;
import java.util.TreeMap;

public class HalfTheMap {

    static void addValues(TreeMap<String, Integer> map)
    {
        map.put("11", 11);
        map.put("33", 33);
        map.put("77", 77);
        map.put("44", 44);
        map.put("55", 55);
        map.put("22", 22);
        //map.put("66", 66);
    }

    public static void main(String[] args) {
        TreeMap<String, Integer> map = new TreeMap<String, Integer>();
        addValues(map);
        System.out.printf("Original Map Initial Values : %s\n",map);

        int size = map.size();
        int midIndex = (size/2) - 1;
        System.out.printf("size : %d \nmid : %d\n", size, midIndex);

        // retrieve key of middle element
        String midKey = (String)map.keySet().toArray()[midIndex];

        // Top half view of the original map
        NavigableMap<String, Integer> topMap = map.headMap(midKey, true);
        System.out.printf("Top half map : %s\n",  topMap);

        // remove the bottom half from original map.
        map.tailMap(midKey, false).clear();
        System.out.printf("Original map after bottom half removed : %s\n", map);
    }

}

打印:

Original Map Initial Values : {11=11, 22=22, 33=33, 44=44, 55=55, 77=77}
size : 6 
mid : 2
Top half map : {11=11, 22=22, 33=33}
Original map after bottom half removed : {11=11, 22=22, 33=33}

当大小对您来说是奇数值以及任何其他适合您需要的微调时,我会将微调减半。

注意:我注意到我在每个条目中使用键和值相同的示例似乎表明它可能是一个解决方案,实际上并不完全正确。虽然它演示了使用一些重要方法来解决问题。 正如上面David Ehrmann所回答的那样,将集合更改为Set而不是Map并使用模态名称和分数的类可能是更好的解决方案。

希望这有帮助。

答案 2 :(得分:0)

但这是一种更简单的方法。

您可以在TreeMap上使用自定义排序器算法。 例如:TreeMap map = new TreeMap(您自己的比较器);

您可以编写自己的比较器来实现Comparator接口。

示例(摘自StackOverflow,不要更精确地了解):

类ValueComparator实现Comparator {

Map<String, Integer> base;
public ValueComparator(Map<String, Integer> base) {
    this.base = base;
}

public int compare(String a, String b) {
    if (base.get(a) >= base.get(b)) {
        return -1;
    } else {
        return 1;
    } // returning 0 would merge keys
}

}

然后,您只需要编辑此代码,按升序排列,然后您只需要删除第一个X.元素。

答案 3 :(得分:-1)

我发现this post可能有所帮助。你无法对Hashmap进行排序,因为它没有明确的顺序。如果您想要对 LinkedHashMap 进行排序,那就是这样做的。 (LinkedHashMap只有一个明确的迭代顺序)

public LinkedHashMap sortHashMapByValues(HashMap passedMap) {
   List mapKeys = new ArrayList(passedMap.keySet());
   List mapValues = new ArrayList(passedMap.values());
   Collections.sort(mapValues);
   Collections.sort(mapKeys);

   LinkedHashMap sortedMap = new LinkedHashMap();

   Iterator valueIt = mapValues.iterator();
   while (valueIt.hasNext()) {
       Object val = valueIt.next();
       Iterator keyIt = mapKeys.iterator();

       while (keyIt.hasNext()) {
           Object key = keyIt.next();
           String comp1 = passedMap.get(key).toString();
           String comp2 = val.toString();

           if (comp1.equals(comp2)){
               passedMap.remove(key);
               mapKeys.remove(key);
               sortedMap.put((String)key, (Double)val);
               break;
           }

       }

   }
   return sortedMap;
}

如果你想删除最低价值,我怀疑这是最简单的事情,你可以做这样的事情来对它们进行排序。

public static Entry<String, Integer> removeLowest(LinkedHashMap<String, Integer> map){
    Entry<String, Integer> lowest = null;
    for(Entry<String,Integer> e: map){
        if(lowest==null || e.getValue().compareTo(lowest.getValue()) < 0){
            lowest = e;
        }
    }
    return lowest;
}

PS:如果适合你,请不要忘记接受我的答案。

更新:如果你想删除一半的地图。你先排序然后再这样做。

public static LinkedHashMap<String, Integer> getTopHalf(LinkedHashMap<String, Integer> map){
    LinkedHashMap<String, Integer> sorted = sortHashMapByValues(map);
    LinkedHashMap<String, Integer> out = new LinkedHashMap<String, Integer>();
    Iterator<Entry<String,Integer>> it = sorted.entrySet().iterator();
    for(int i = 0;  i<map.size()/2; i++){
        Entry<String, Integer> e = it.next();
        out.put(e.getKey(), e.getValue());
    }
    return out;
}