简体   繁体   English

按值从高到低对 Hashmap 进行排序

[英]Sorting Hashmap by values from High to low

I am trying to sort a hashmap that has a structure of by the value from high to Low.我正在尝试对结构为 hashmap 的值从高到低进行排序。

I have created a function below to sort the data.我在下面创建了一个 function 来对数据进行排序。

public static void SortDataHighToLow (Map <String, Integer> UnsortedMap){
    List <Integer> list = new ArrayList(UnsortedMap.keySet());
    Collections.sort(list,new Comparator <Integer>(){

        @Override
        public int compare(Integer arg0, Integer arg1) {

            return arg0-arg1;
        }
    });

    Map <String, Integer> sortedMap = new LinkedHashMap<>();

    for (Integer keys: list){
        sortedMap.put(UnsortedMap.toString(), keys);
    }

    System.out.println(sortedMap);
}

I am recieving the error below:我收到以下错误:

Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap') Exception in thread "main" java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integer (java.lang.String and java.lang.Integer are in module java.base of loader 'bootstrap ')

I believe my error is caused by the for() above that I cannot read the Key value.我相信我的错误是由上面的 for() 引起的,我无法读取 Key 值。

What adjustment should I make?我应该做什么调整?

Thanks for the help.谢谢您的帮助。

This is a comparator that do the job:这是一个完成这项工作的比较器:

public class MapKeyByValueComparator<K, T> implements Comparator<K> {

    private final Map<K, T> map;

    private final Comparator<T> comparator;

    public MapKeyByValueComparator(Map<K, T> map, Comparator<T> comparator) {
        this.map = map;
        this.comparator = comparator;
    }

    @Override
    public int compare(K o1, K o2) {
        int ritem = comparator.compare(map.get(o1), map.get(o2));
        // CAN NOT RETURNS 0, otherwise key with the same value will be overridden
        if (ritem == 0) {
            ritem = 1;
        }
        return ritem;
    }

}

And then you can use a TreeMap as:然后您可以将TreeMap用作:

Map<something, somethig> map = new TreeMap<>(comparator):
map.addAll(...);

But PAY ATTENTION , this brokes the contract of Comparable但是请注意,这违反了Comparable的合同

It is strongly recommended (though not required) that natural orderings be consistent with equals.强烈建议(虽然不是必需的)自然排序与 equals 一致。 This is so because sorted sets (and sorted maps) without explicit comparators behave "strangely" when they are used with elements (or keys) whose natural ordering is inconsistent with equals.之所以如此,是因为没有显式比较器的排序集(和排序映射)在与自然排序与 equals 不一致的元素(或键)一起使用时表现得“奇怪”。 In particular, such a sorted set (or sorted map) violates the general contract for set (or map), which is defined in terms of the equals method.特别是,这样的有序集合(或有序映射)违反了集合(或映射)的一般契约,该契约是根据 equals 方法定义的。

Upon the answer came from @deHaar my problem got resolved.当@deHaar 给出答案后,我的问题就解决了。 The code is below.代码如下。

private static <K, V> Map<K, V> sortByValue(Map<K, V> map) {
List<Entry<K, V>> list = new LinkedList<>(map.entrySet());
Collections.sort(list, new Comparator<Object>() {
    @SuppressWarnings("unchecked")
    public int compare(Object o1, Object o2) {
        return ((Comparable<V>) ((Map.Entry<K, V>) (o1)).getValue()).compareTo(((Map.Entry<K, V>) (o2)).getValue());
    }
});

Map<K, V> result = new LinkedHashMap<>();
for (Iterator<Entry<K, V>> it = list.iterator(); it.hasNext();) {
    Map.Entry<K, V> entry = (Map.Entry<K, V>) it.next();
    result.put(entry.getKey(), entry.getValue());
}

return result;

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM