如何在java流中按降序排序LinkedHashMap?
要按升序对其进行排序,我可以使用:
myMap.entrySet().stream() .sorted(Map.Entry.comparingByValue()) .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
我怎么能按降序排列呢?
自Java 1.8以来java.util.Comparator.reversed()
myMap.entrySet().stream() .sorted(Map.Entry.comparingByValue().reversed()) .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))
相比)得到一个颠倒顺序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));
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 mergeFunction, Supplier
返回将元素累积到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 hashMap = new LinkedHashMap(); hashMap.put(1,5); hashMap.put(7,9); hashMap.put(3,8); hashMap.put(10,5); Function,Integer> keyMapper = x->x.getKey(); Function,Integer> valueMapper = x->x.getValue(); BinaryOperator< Integer> mergeFunction = (x,y)->x;// we do not want any merging here Supplier> mapRequired =()-> {return new LinkedHashMap();};// to maintain order we must use LinkedHashMap Comparator> 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) ) ); } }