java 如何在java流中按值降序对LinkedHashMap进行排序?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29860667/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:01:43  来源:igfitidea点击:

How to sort a LinkedHashMap by value in decreasing order in java stream?

javasortingjava-8java-streamlinkedhashmap

提问by Oxydron

To sort it int ascending order I can use:

要按升序对其进行排序,我可以使用:

myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue())
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

How can I do it in decreasing order?

我怎样才能按降序进行?

回答by Misha

To sort in reverse order, pass Comparator.reverseOrder()as parameter to comparingByValue.

要以相反的顺序排序,请将Comparator.reverseOrder()作为参数传递给comparingByValue

To get a LinkedHashMap, you must specifically request one with the 4-argument toMap(). If you don't specify what kind of a map you want, you will get whatever the default is, which currently happens to be a HashMap. Since HashMapdoesn't preserve the order of elements, it will definitely not do for you.

要获得LinkedHashMap,您必须特别请求带有 4 个参数的toMap()。如果你没有指定你想要什么样的地图,你会得到任何默认值,目前恰好是HashMap. 由于HashMap不保留元素的顺序,它绝对不会为您做。

myMap.entrySet().stream()
        .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
        .collect(Collectors.toMap(
                Map.Entry::getKey, 
                Map.Entry::getValue, 
                (x,y)-> {throw new AssertionError();},
                LinkedHashMap::new
        ));

With static imports, it becomes a bit more pleasant:

使用静态导入,它变得更加愉快:

myMap.entrySet().stream()
        .sorted(comparingByValue(reverseOrder()))
        .collect(toMap(
                Map.Entry::getKey, 
                Map.Entry::getValue, 
                (x,y)-> {throw new AssertionError();},
                LinkedHashMap::new
        ));

回答by Eran

You can pass whatever Comparator you wish to comparingByValue.

你可以传递任何你想要的 Comparator comparingByValue

For example (I hope I got the syntax right, since I can't test it):

例如(我希望我的语法正确,因为我无法测试它):

myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue((v1,v2)->v2.compareTo(v1)))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

By comparing the values of the two entries in the opposite order, using the natural ordering (Comparable's compareTo), you get a reversed order compared to what comparingByValue()(which is equivalent to comparingByValue((v1,v2)->v1.compareTo(v2))) will give you.

通过以相反的顺序比较两个条目的值,使用自然顺序 ( Comparable's compareTo),您会得到与comparingByValue()( 等价于comparingByValue((v1,v2)->v1.compareTo(v2))) 给您的顺序相反的顺序。

BTW, I'm not sure that Collectors.toMapreturns a LinkedHashMapinstance, and even if it currently does, it can change in the future, since the Javadoc doesn't mention it, so you can't rely on it.

顺便说一句,我不确定Collectors.toMap返回一个LinkedHashMap实例,即使它现在返回,它也可以在未来改变,因为 Javadoc 没有提到它,所以你不能依赖它。

To make sure that the resulting Map would be a LinkedHashMap, you should use a different variant of toMap :

为了确保生成的 Map 是 LinkedHashMap,您应该使用 toMap 的不同变体:

myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue((v1,v2)->v2.compareTo(v1)))
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (v1,v2)->v1, LinkedHashMap::new));

回答by Shirishkumar Bari

Stream has as sortedmethod which accepts a comparator hence you can directly use the comparator as (x,y)->y.getKey().compareTo(x.getKey())for descending sorting. To sort the map in ascending we can reverse the ordering as (x,y)->x.getKey().compareTo(y.getKey())

Stream 具有sorted接受比较器的as方法,因此您可以直接使用比较器(x,y)->y.getKey().compareTo(x.getKey())进行降序排序。要按升序对地图进行排序,我们可以将顺序颠倒为(x,y)->x.getKey().compareTo(y.getKey())

for consolidating result back into LinkedHashMap we can use Collectors toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)which Returns a Collector that accumulates elements into a Map whose keys and values are the result of applying the provided mapping functions to the input elements.

为了将结果合并回 LinkedHashMap,我们可以使用收集器toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier),它返回一个收集器,该收集器将元素累积到 Map 中,其键和值是将提供的映射函数应用于输入元素的结果。

Working code

工作代码

import java.io.*;
import java.util.*;
import java.util.function.*;
import java.util.stream.Collectors;
import java.util.stream.*;
public class HelloWorld{

     public static void main(String []args){
        LinkedHashMap<Integer,Integer> hashMap = new LinkedHashMap<Integer,Integer>(); 
            hashMap.put(1,5);
            hashMap.put(7,9);
            hashMap.put(3,8);
            hashMap.put(10,5);

            Function<Map.Entry<Integer,Integer>,Integer> keyMapper = x->x.getKey();
            Function<Map.Entry<Integer,Integer>,Integer> valueMapper = x->x.getValue();
            BinaryOperator< Integer> mergeFunction = (x,y)->x;// we do not want any merging here 
            Supplier<LinkedHashMap<Integer,Integer>> mapRequired =()-> {return new LinkedHashMap<Integer,Integer>();};// to maintain order we must use LinkedHashMap
            Comparator<Map.Entry<Integer,Integer>> descendingComparator = (x,y)->y.getKey().compareTo(x.getKey());
            // we can write it as  

        System.out.println(
                  hashMap.entrySet().stream()
                             .sorted (descendingComparator) 
                             .collect(Collectors.toMap(
                                                      keyMapper,
                                                       valueMapper,
                                                       mergeFunction,
                                                       mapRequired)
                                           )
                );           

// or even by writing below will also work

        System.out.println(
                  hashMap.entrySet().stream()
                             .sorted ((x,y)->y.getKey().compareTo(x.getKey())) 
                             .collect(Collectors.toMap(
                                                       x->x.getKey(),
                                                       x->x.getValue(),
                                                       (x,y)->x,
                                                       LinkedHashMap::new)
                                           )
                );           
     }


}

回答by Ril Dank

Since Java 1.8 java.util.Comparator.reversed()

从 Java 1.8 java.util.Comparator.reversed() 开始

myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));