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
How to sort a LinkedHashMap by value in decreasing order in java stream?
提问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 HashMap
doesn'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.toMap
returns a LinkedHashMap
instance, 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 sorted
method 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));