Java

在公司做项目的过程中,发现对对象进行计数的操作十分常见,而且还需要对这些对象分别按照键或者值(按值排序比较常见)进行排序,本篇博文分别介绍Map按键或者值进行排序。

按键排序

TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现,该映射根据其键的自然顺序进行排序,默认是按照升序进行排列的,如示例一。我们可以使用比较器:Comparator。Comparator可以对集合对象或者数组进行排序的比较器接口,实现该接口的public compare(T o1,To2)方法即可实现排序,如示例二。

  • 示例一
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("b", 80);
map.put("a", 90);
map.put("d", 60);
Frequency frequency = new Frequency();
List<Frequency.Token> res = frequency.getSortList(map);
for (Frequency.Token token : res) {
    System.out.println(token.getEntry() + ":" + token.getCount());}
//a:90
//b:80
//d:60
  • 示例二
Map<String, Integer> map = new TreeMap<String, Integer>(
     new Comparator<String>() {
        public int compare(String obj1, String obj2) {
               // 降序排序
               return obj2.compareTo(obj1);
        }
     });
     map.put("b", 80);
     map.put("a", 90);
     map.put("d", 60);
     for (String str:map.keySet()){
         System.out.println(str+":"+map.get(str));
     }
//d:60
//b:80
//a:90

按值排序

按值排序在开发中我遇见过两种解决方案,接下来将进行介绍。(TreeMap 和 HashMap 类似)

  • 方案一
    借助于Collections的sort(List list, Comparator
//按值降序排列
public List<Map.Entry<String, Integer>> mapSortByValue(Map<String, Integer> map) {
        List<Map.Entry<String, Integer>> mapList = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
        Collections.sort(mapList, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
        return mapList;
    }


    @Test
    public void test() {
        //Map<String, Integer> map = new TreeMap<String, Integer>();
        Map<String, Integer> map = new HashMap<String, Integer>();

        map.put("JF", 80);
        map.put("Messi", 90);
        map.put("Lionel", 60);
        List<Map.Entry<String, Integer>> mapList = mapSortByValue(map);
        for (Map.Entry<String, Integer> map1 : mapList) {
            System.out.println(map1.getKey() + ":" + map1.getValue());
        }
    }
//Messi:90
//JF:80
//Lionel:60
  • 方案二
    自己定义一个含有键、值的类,并实现 Comparable接口。
public class Frequency {

    public List<Token> getSortList(Map<String, Integer> freq) {
        List<Token> tokens = new ArrayList<Token>(freq.size());
        for (String entry : freq.keySet()) {
            tokens.add(new Token(entry, freq.get(entry)));
        }
        Collections.sort(tokens);
        return tokens;
    }

    public class Token implements Comparable<Token> {
        private String entry;
        private Integer count;

        public Token(String entry, Integer count) {
            this.entry = entry;
            this.count = count;
        }

        public String getEntry() {
            return entry;
        }

        public Integer getCount() {
            return count;
        }

        public int compareTo(Token o) {
            if (o == null) {
                return 0;
            }
            return o.count.compareTo(count);
        }
    }
}
@Test
    public void Test1() {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("b", 80);
        map.put("a", 90);
        map.put("d", 60);
        Frequency frequency = new Frequency();
        List<Frequency.Token> res = frequency.getSortList(map);
        for (Frequency.Token token : res) {
            System.out.println(token.getEntry() + ":" + token.getCount());
        }
    }
//Messi:90
//JF:80
//Lionel:60