在Java中按值对Map进行排序

3

我正在尝试对 java.util.Map 进行如下排序。

public final class SortMapByValue <K, V extends Comparable<? super V>> implements Comparator<Map.Entry<K, V>>
{
    @Override
    public int compare(Entry<K, V> o1, Entry<K, V> o2) {
        return (o1.getValue()).compareTo(o2.getValue());
    }

    public static <K, V extends Comparable<? super V>> Map<K, V> sortMapByValue(Map<K, V> unsortedMap)
    {
        List<Map.Entry<K, V>> list = new LinkedList<Map.Entry<K, V>>(unsortedMap.entrySet());            
        Collections.sort(list);  //Compiler error here.
        Map<K, V> sortedMap = new LinkedHashMap<K, V>();

        for (Map.Entry<K, V> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }
        return sortedMap;
    }
}

如代码中所注释的那样,它会发出以下编译时错误。

no suitable method found for sort(List<Entry<K,V>>)
    method Collections.<T#1>sort(List<T#1>,Comparator<? super T#1>) is not applicable
      (cannot instantiate from arguments because actual and formal argument lists differ in length)
    method Collections.<T#2>sort(List<T#2>) is not applicable
      (inferred type does not conform to declared bound(s)
        inferred: Entry<K,V>
        bound(s): Comparable<? super Entry<K,V>>)
  where K,V,T#1,T#2 are type-variables:
    K extends Object declared in method <K,V>sortMapByValue(Map<K,V>)
    V extends Comparable<? super V> declared in method <K,V>sortMapByValue(Map<K,V>)
    T#1 extends Object declared in method <T#1>sort(List<T#1>,Comparator<? super T#1>)
    T#2 extends Comparable<? super T#2> declared in method <T#2>sort(List<T#2>)

以下是在 sortMapByValue() 方法中以以下方式完成的。

Collections.sort(list, new Comparator<Map.Entry<K, V>>()
{
    @Override
    public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
        return (o1.getValue()).compareTo(o2.getValue());
    }
});

相反,我想修复该错误并遵循这种方式(避免使用匿名比较器)。如何解决此错误?


3
你有一个Entry列表。类Entry没有实现Comparable接口。然而,Collections.sort(..)期望一个实现了Comparable接口的类型的列表。 - Sotirios Delimanolis
所以你有一些无法编译的代码,还有一些完美运行的代码。那些完美运行的代码却不能满足你的需求,而那些无法编译的代码又让你苦恼无比。我的理解正确吗? - ruakh
你需要将比较器传递给Collections.sort,例如像Collections.sort(list, new SortMapByValue()); - Gábor Bakos
可能是如何在Java中按值对Map<Key, Value>进行排序?的重复问题。 - Svetlin Zarev
可能会被关闭为“不清楚你在问什么”,真的吗? :) - Tiny
1个回答

8

Map.Entry没有实现Comparable接口,因此Collections.sort(List<Entry>)无法知道如何对条目进行排序。因此,您需要提供一个Comparator。

但是,由于您的SortMapByValue已经实现了Comparator接口,因此可以直接使用该类的实例:

Collections.sort(list, new SortMapByValue<>());

请注意,使用Java 8可以显著缩短代码长度:

public static <K, V extends Comparable<? super V>> Map<K, V> sortMapByValue(Map<K, V> unsortedMap) {
    return unsortedMap.entrySet().stream()
            .sorted(comparing(Entry::getValue))
            .collect(toMap(Entry::getKey, Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接