4.5 Map 按值排序

在Java中,我们用TreeMap 类进行map的按Key排序。这个类实用起来很方便。但是有时候我们需要对一个map进行按值排序。如何对map进行按值排序,是Java开发者常问的问题,在这篇文章中,我将编写最好的按值排序方法。

1.本地方法

以下是对的map的排序解决方法,这通常用于计算单词出现的频率。

import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeMap;
 
public class SortMapByValue {
 
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("a", 10);
        map.put("b", 30);
        map.put("c", 50);
        map.put("d", 40);
        map.put("e", 20);
        System.out.println(map);
 
        TreeMap sortedMap = sortMapByValue(map);  
        System.out.println(sortedMap);
    }
 
    public static TreeMap sortMapByValue(HashMap map){
        Comparator comparator = new ValueComparator(map);
        //TreeMap is a map sorted by its keys. 
        //The comparator is used to sort the TreeMap by keys. 
        TreeMap result = new TreeMap(comparator);
        result.putAll(map);
        return result;
    }
}

下面是comparator类的具体实现:

// a comparator that compares Strings
class ValueComparator implements Comparator{
 
    HashMap map = new HashMap();
 
    public ValueComparator(HashMap map){
        this.map.putAll(map);
    }
 
    @Override
    public int compare(String s1, String s2) {
        if(map.get(s1) >= map.get(s2)){
            return -1;
        }else{
            return 1;
        }   
    }
}

在这个解决方案中,我们利用TreeMap对Map进行排序,当创建Map时候,我们给它一个比较器。这个比较器接受字符串,比较它们作为key在map中映射的值。

这个方法运行良好,但是仅仅适用String和Integer的对。如果你想对一个包含其他类型的键值的Map进行排序,需要重写它。因此一个通用的方法更好。

2. 更通用的解决办法

我们可以忽略泛型,让方法适用于任何类型,如下:

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
 
public class Solution {
    public static void main(String[] args) {
        HashMap map = new HashMap();
        map.put("a", 10);
        map.put("b", 30);
        map.put("c", 50);
        map.put("d", 40);
        map.put("e", 20);
        System.out.println(map);
 
        Map sortedMap = sortByValue(map);
        System.out.println(sortedMap);
    }
 
    public static Map sortByValue(Map unsortedMap) {
        Map sortedMap = new TreeMap(new ValueComparator(unsortedMap));
        sortedMap.putAll(unsortedMap);
        return sortedMap;
    }
 
}
 
class ValueComparator implements Comparator {
    Map map;
 
    public ValueComparator(Map map) {
        this.map = map;
    }
 
    public int compare(Object keyA, Object keyB) {
        Comparable valueA = (Comparable) map.get(keyA);
        Comparable valueB = (Comparable) map.get(keyB);
        return valueB.compareTo(valueA);
    }
}

这个解决方法不是类型安全的,我们需要一个类型安全的和更通用的解决方法。

3. 用通用的类型

public class SortMapByValue {
 
    public static void main(String[] args) {
        //  Map
        HashMap map = new HashMap();
        map.put("a", 10);
        map.put("b", 30);
        map.put("c", 50);
        map.put("d", 40);
        map.put("e", 20);
        System.out.println(map);
 
 
        Comparator comparator = new ValueComparator(map);
        TreeMap result = new TreeMap(comparator);
        result.putAll(map);
 
        System.out.println(result);
 
        //  Map
 
        HashMap map2 = new HashMap();
        map2.put(1, 10);
        map2.put(2, 30);
        map2.put(3, 50);
        map2.put(4, 40);
        map2.put(5, 20);
        System.out.println(map2);
 
        Comparator comparator2 = new ValueComparator(map2);
        TreeMap result2 = new TreeMap(comparator2);
        result2.putAll(map2);
 
        System.out.println(result2);
 
    }
 
}
// a comparator using generic type
class ValueComparator> implements Comparator{
 
    HashMap map = new HashMap();
 
    public ValueComparator(HashMap map){
        this.map.putAll(map);
    }
 
    @Override
    public int compare(K s1, K s2) {
        return -map.get(s1).compareTo(map.get(s2));//descending order   
    }
}

4.另外一种利用泛型的方法

public static > Map sortByValue(Map map) {
    List> list = new LinkedList<>(map.entrySet());
    Collections.sort(list, new Comparator>() {
        @Override
        public int compare(Map.Entry e1, Map.Entry e2) {
            return (e1.getValue()).compareTo(e2.getValue());
        }
    });
 
    Map result = new LinkedHashMap<>();
    for (Map.Entry entry : list) {
        result.put(entry.getKey(), entry.getValue());
    }
 
    return result;
}

你可能感兴趣的:(4.5 Map 按值排序)