Java8中按降序排序Map

4
private static <K, V extends Comparable<? super V>> Map<K, V>
    sortByValue( Map<K, V> map )
    {
        Map<K, V> result = new LinkedHashMap<>();
        Stream<Map.Entry<K, V>> st = map.entrySet().stream();

        st.sorted( Map.Entry.comparingByValue() )
                .forEachOrdered( e -> result.put(e.getKey(), e.getValue()) );

        return result;
    }

这是来自这篇文章的一个示例。它可以正常工作,但问题在于它按升序排序。我该如何将其更改为降序?
我可以像这样做:
public static <K, V extends Comparable<? super V>> Map<K, V>
sortByValue( Map<K, V> map )
{
    List<Map.Entry<K, V>> list =
            new LinkedList<Map.Entry<K, V>>( map.entrySet() );
    Collections.sort( list, new Comparator<Map.Entry<K, V>>()
    {
        public int compare( Map.Entry<K, V> o1, Map.Entry<K, V> o2 )
        {
            return (o2.getValue()).compareTo( o1.getValue() );//change o1 with o2
        }
    } );

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

我可以通过更改此行中的顺序来完成:return (o2.getValue()).compareTo( o1.getValue() ); 但是我想尝试使用lambda表达式。


1
在我们回答这个问题之前,你自己试过什么? 你找到答案的地方在哪里,你尝试了什么,你是否查阅了此代码中所见 API 调用的文档等? - Mike 'Pomax' Kamermans
1
顺便提一下,不要使用 .forEach/.forEachOrdered 向映射中添加条目,而是使用 Collectors.toMap 进行收集。 - Alexis C.
2个回答

15
你可以使用Comparator 的默认方法reversed()来反转比较的顺序以实现降序排序。
这里类型推断似乎有点问题,但是提供显式类型参数给 comparingByValue() 可以解决这个问题。
st.sorted( Map.Entry.<K, V>comparingByValue().reversed() )
       .forEachOrdered(e -> result.put(e.getKey(), e.getValue()));

0

你可以使用已提供的比较器,将compareTo返回值乘以-1或简单地交换参数(以解决边角情况)。

(a,b)-->{comparingByValue().compareTo(b,a)}

为什么不直接使用compareTo(b, a)呢? - Andy Turner
从数学上讲,这两件事是等价的,就性能而言,你的版本更快。最终我认为这并不重要。 - HopefullyHelpful
不完全等价:比较器可能返回 Integer.MIN_VALUE 表示 a < b - Andy Turner

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