java中Map按值排序

在许多场合下,经常需要对Map进行排序,排序的依据是Map中的值。简单的例子比如根据Map<Integer,Integer>代表学生分数,想要根据分数从高到低排列该Map。更复杂的例子中,Map<String,List<Flight>>代表一组共享航班,key为共享航班号,value为共享该航班号的所有航班,其中执飞航班位于第一个元素,我们现在想根据执飞航班的时间排序。

解决方案如下:

    private LinkedHashMap<String, List<Flight>> sortHashMapByValues(
            Map<String, List<Flight>> passedMap , Comparator<List<Flight>> comparator) {
        List<String> mapKeys = new ArrayList<>(passedMap.keySet());
        List<List<Flight>> mapValues = new ArrayList<>(
                passedMap.values());
        Collections.sort(mapValues, comparator);
        Collections.sort(mapKeys);

        LinkedHashMap<String, List<Flight>> sortedMap = new LinkedHashMap<>();

        Iterator<List<Flight>> valueIt = mapValues.iterator();
        while (valueIt.hasNext()) {
            List<Flight> val = valueIt.next();
            Iterator<String> keyIt = mapKeys.iterator();

            while (keyIt.hasNext()) {
                String key = keyIt.next();
                List<Flight> comp1 = passedMap.get(key);
                List<Flight> comp2 = val;

                if (comp1.equals(comp2)) {
                    keyIt.remove();
                    sortedMap.put(key, val);
                    break;
                }
            }
        }
        return sortedMap;
    }

Comparator的一个实现如下:

public class RTFlightArrivalComparator implements
        Comparator<List<Flight>> {

    @Override
    public int compare(List<Flight> o1,
            List<Flight> o2) {

        Flight first1 = o1.get(0);
        Flight first2 = o2.get(0);

        return first1.getSta().compareTo(first2.getSta());
    }

}

LinkedHashMap维护的是一个双向链表,其顺序通过与插入顺序相关(Insertion-Order),这种方案效率比较低。 下面是使用TreeMap来实现排序的一个例子。TreeMap会对其key进行排序,可以接受自定义的比较器Comparator:

import java.util.Comparator;
import java.util.HashMap;
import java.util.TreeMap;

public class SortMapByValue {

    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        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<String, Integer> sortedMap = sortMapByValue(map);  
        System.out.println(sortedMap);
    }

    public static TreeMap<String, Integer> sortMapByValue(HashMap<String, Integer> map){
        Comparator<String> comparator = new ValueComparator(map);
        //TreeMap is a map sorted by its keys. 
        //The comparator is used to sort the TreeMap by keys. 
        TreeMap<String, Integer> result = new TreeMap<String, Integer>(comparator);
        result.putAll(map);
        return result;
    }
}

在实现key的比较器时,因为我们想要根据值排序,所以其顺序依赖于值,因此在比较器构造的时候,需要传入待排序的Map:

// a comparator that compares Strings
class ValueComparator implements Comparator<String>{

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

    public ValueComparator(HashMap<String, Integer> 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;
        }   
    }
}

上述代码只能处理特定类型的Map,下面使用泛型来实现更通用的方法:

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<String, Integer> map = new HashMap<String, Integer>();
        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);
    }
}
// a comparator using generic type
class ValueComparator<K, V extends Comparable<V>> implements Comparator<K>{

    HashMap<K, V> map = new HashMap<K, V>();

    public ValueComparator(HashMap<K, V> map){
        this.map.putAll(map);
    }

    @Override
    public int compare(K s1, K s2) {
        return -map.get(s1).compareTo(map.get(s2));//descending order   
    }
}
public class SortMapByValue {

    public static void main(String[] args) {
        // <String, Integer> Map
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        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<String> comparator = new ValueComparator<String, Integer>(map);
        TreeMap<String, Integer> result = new TreeMap<String, Integer>(comparator);
        result.putAll(map);

        System.out.println(result);

        // <Integer, Integer> Map

        HashMap<Integer, Integer> map2 = new HashMap<Integer, Integer>();
        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<Integer> comparator2 = new ValueComparator<Integer, Integer>(map2);
        TreeMap<Integer, Integer> result2 = new TreeMap<Integer, Integer>(comparator2);
        result2.putAll(map2);

        System.out.println(result2);

    }

}

(完)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值