按升序排序,我可以使用:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
我该如何按降序排序?
按升序排序,我可以使用:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
我该如何按降序排序?
要以相反的顺序排序,将Comparator.reverseOrder()
作为参数传递给comparingByValue
。
要获得一个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
));
使用静态导入后,情况会变得更加愉悦:
myMap.entrySet().stream()
.sorted(comparingByValue(reverseOrder()))
.collect(toMap(
Map.Entry::getKey,
Map.Entry::getValue,
(x,y)-> {throw new AssertionError();},
LinkedHashMap::new
));
comparingByValue
中。myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue((v1,v2)->v2.compareTo(v1)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
通过使用自然排序 (Comparable
的 compareTo
) 反向比较两个相反顺序的条目的值,你将获得一个与 comparingByValue()
相反的顺序(该方法等同于 comparingByValue((v1,v2)->v1.compareTo(v2))
)。
顺便提一下,我不确定 Collectors.toMap
是否返回一个 LinkedHashMap
实例,即使它目前确实是这样,由于 Javadoc 没有提到这点,所以你不能依赖它。
为了确保生成的 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));
comparingByValue
),lambda表达式的类型参数是V
而不是Entry<K,V>
,因为您提供了一个比较器来比较值,所以您可以将其更改为comparingByValue((v1, v2)->v2.compareTo(v1))
或者更好地使用comparingByValue(reverseOrder())
,就像@Misha建议的那样... - Alexis C.toMap
的源代码,你会发现它返回toMap(keyMapper, valueMapper, throwingMerger(), HashMap::new)
。因此,基本上你的实现不会做什么有用的事情(尽管你是从OP的问题中获取的)。 - Alexis C.Stream有sorted
方法来接受比较器,因此您可以直接使用比较器作为(x,y)->y.getKey().compareTo(x.getKey())
进行降序排序。要按升序对映射进行排序,我们可以反转顺序,如(x,y)->x.getKey().compareTo(y.getKey())
要将结果合并回LinkedHashMap,我们可以使用Collectors toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
,它会返回一个收集器,该收集器可以将元素累积到Map中,其中键和值是将提供的映射函数应用于输入元素的结果。
工作代码
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)
)
);
}
}
自从Java 1.8以来,java.util.Comparator.reversed()。
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue().reversed())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
.sorted(Map.Entry.comparingByValueReverse())
- Oxydron