我对Java比较陌生,经常发现需要对值进行Map<Key,Value>排序。

由于这些值不是唯一的,我发现自己将keySet转换为一个数组,并使用自定义比较器通过数组排序对该数组进行排序,该比较器根据与该键关联的值进行排序。

有没有更简单的方法?


当前回答

使用java.util.TreeMap。

映射根据其键的自然顺序进行排序,或由创建映射时提供的Comparator进行排序,具体取决于使用的构造函数

其他回答

    Map<String, Integer> map = new HashMap<>();
    map.put("b", 2);
    map.put("a", 1);
    map.put("d", 4);
    map.put("c", 3);
    
    // ----- Using Java 7 -------------------
    List<Map.Entry<String, Integer>> entries = new ArrayList<>(map.entrySet());
    Collections.sort(entries, (o1, o2) -> o1.getValue().compareTo(o2.getValue()));
    System.out.println(entries); // [a=1, b=2, c=3, d=4]


    // ----- Using Java 8 Stream API --------
   map.entrySet().stream().sorted(Map.Entry.comparingByValue()).forEach(System.out::println); // {a=1, b=2, c=3, d=4}

    

根据上下文,使用java.util.LinkedHashMap<T>来记住项目在映射中的放置顺序。否则,如果您需要根据值的自然排序对值进行排序,我建议您维护一个单独的List,该List可以通过Collections.sort()进行排序。

为每个值创建一个条目列表,其中对值进行排序需要Java 8或更高版本

Map<Double,List<Entry<String,Double>>> sorted =
map.entrySet().stream().collect( Collectors.groupingBy( Entry::getValue, TreeMap::new,
    Collectors.mapping( Function.identity(), Collectors.toList() ) ) );

使用映射{[A=99.5],[B=67.4],[C=67.3],[D=67.3]}得到{67.3=[D=67.3],67.4=[B=67.4,C=67.4],99.5=[A=99.5]}

…以及如何逐个访问每个条目:

sorted.entrySet().forEach( e -> e.getValue().forEach( l -> System.out.println( l ) ) );

D=67.3 B=67.4 C=67.4 A=99.5

使用LinkedList

//Create a list by HashMap
List<Map.Entry<String, Double>> list = new LinkedList<>(hashMap.entrySet());

//Sorting the list
Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
    public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
        return (o1.getValue()).compareTo(o2.getValue());
    }
});

//put data from sorted list to hashmap
HashMap<String, Double> sortedData = new LinkedHashMap<>();
for (Map.Entry<String, Double> data : list) {
    sortedData.put(data.getKey(), data.getValue());
}

System.out.print(sortedData);

我已经查看了给定的答案,但很多答案比需要的要复杂,或者在多个键具有相同值时删除映射元素。

以下是我认为更适合的解决方案:

public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
    Comparator<K> valueComparator =  new Comparator<K>() {
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return compare;
        }
    };
    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

请注意,地图是从最高值到最低值排序的。