如何先按值排序 Map 条目,然后按键排序并将排序的键放入列表中?

How to sort Map entries by values first, then by key and put the ordered keys in a List?

我有一个 HashMap :

private Map<String,Integer> matchesWonByTeam= new HashMap<String,Integer>();

使用集合和比较器最短、最简单的方法是什么?

Return条目集,创建一个列表,然后使用匿名比较器实现对条目进行排序。

List<Entry<String,Integer>> matchesWonList = new ArrayList<Entry<String,Integer>>(matchesWonByTeam.entrySet());
Collections.sort(matchesWonList , new   Comparator<Entry<String,Integer>>(){
    //implement your comparator here.
});

这个有效:

Map<String,Integer> map = new HashMap<String,Integer>();
/*...fill map...*/

SortedSet<Map.Entry<String, Integer>> sortedSet = new TreeSet<>(new Comparator<Map.Entry<String, Integer>>() {
    @Override
    public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
        int res = e1.getValue().compareTo(e2.getValue());
        if(res == 0)
            return e1.getKey().compareTo(e2.getKey());
        return res * -1;
    }
});
sortedSet.addAll(map.entrySet());

List<String> list = new ArrayList<>();
for(Map.Entry<String, Integer> e: sortedSet)
    list.add(e.getKey());

这是假设您希望顺序从最大 Integer 到最小 Integer。如果不是,请在返回 res 时删除 * -1

这里有一些 Java 8 给你。

    final Comparator<Map.Entry<String, Integer>> byMatchesWon = 
            Comparator.comparing(Map.Entry::getValue, Comparator.reverseOrder());
    final Comparator<Map.Entry<String, Integer>> byTeamName = 
            Comparator.comparing(Map.Entry::getKey);

    final List<String> hasToBeReturned = matchesWonByTeam
            .entrySet().stream()
            .sorted(byMatchesWon.thenComparing(byTeamName))
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());

注意 - 内联比较器在这里不起作用,编译器将无法推断出正确的实现。

您可以使用函数式编程来做到这一点:

final Map<String, Integer> map = new HashMap<>();
map.put("test", 1);
map.put("test1", 3);
map.put("test3", 4);
map.put("test2", 75);
map.put("a", 75);
map.put("test100", 100);

final List<String> test = map
        .entrySet()
        .stream()
        .sorted((Entry<String, Integer> o1, Entry<String, Integer> o2) -> {
              return o1.getValue().equals(o2.getValue()) ? 
                          o1.getKey().compareTo(o2.getKey()) 
                              : o1.getValue().compareTo(o2.getValue());
          })
        .map(e -> e.getKey())
        .collect(Collectors.toList());

for(String s : test)
      System.out.println(s); 

这个例子会输出

test test1 test3 a test2 test100

matchesWonByTeam 现在将是一个维护顺序的 linkedHashMap。

matchesWonByTeam = matchesWonByTeam.entrySet()
                .stream()
                .sorted(
                        new Comparator<Map.Entry<String, Integer>>() {
                            @Override
                            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {

                                if(o1.getValue() < o2.getValue()) {
                                    return  -1;
                                }
                                if(o1.getValue() > o2.getValue()) {
                                    return 1;
                                }
                                return o1.getKey().compareTo(o2.getKey());

                            }
                        }
                )
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));