【问题标题】:How to sort Map entries by values first, then by key and put the ordered keys in a List?如何首先按值对 Map 条目进行排序,然后按键排序并将排序的键放入列表中?
【发布时间】:2015-04-26 21:37:10
【问题描述】:

我有一个HashMap

private Map<String,Integer> matchesWonByTeam= new HashMap<String,Integer>();
  • 我需要按赢得的比赛(值)对这些球队进行排序,并返回一个包含球队名称的 ArrayList。
  • 如果其中任何一支球队赢得的比赛数量相同,则需要按字母顺序排列。

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

【问题讨论】:

  • HashMap 是无序的。将名称移动到 ArrayList 并根据从 HashMap 检索到的值对其进行排序。
  • 遍历它们并将它们添加到TreeMap(如果您在创建时提供Comparator,它们会保持排序)
  • 可能是这个stackoverflow.com/questions/109383/…的副本

标签: java sorting dictionary collections comparator


【解决方案1】:

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));

【讨论】:

    【解决方案2】:

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

    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

    【讨论】:

      【解决方案3】:

      这行得通:

      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

      【讨论】:

        【解决方案4】:

        这里有一些 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());
        

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

        【讨论】:

        • 您通常可以通过为 lambda 参数之一提供类型见证或显式类型来内联比较器。
        【解决方案5】:

        返回条目集,创建一个 List,然后使用匿名 Comparator 实现对条目进行排序。

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

        【讨论】:

          猜你喜欢
          • 2013-11-19
          • 2016-11-03
          • 2014-01-18
          • 2023-04-06
          • 2021-11-22
          • 2019-06-26
          • 1970-01-01
          • 2020-03-19
          • 2023-03-05
          相关资源
          最近更新 更多