如何在 java 流中按值降序对 LinkedHashMap 进行排序?
How to sort a LinkedHashMap by value in decreasing order in java stream?
要按升序排序,我可以使用:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
如何按降序排列?
您可以将任何您想要的比较器传递给 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
returns 是一个 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));
要倒序排序,将 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
));
Stream 具有接受比较器的 sorted
方法,因此您可以直接使用比较器作为 (x,y)->y.getKey().compareTo(x.getKey())
进行降序排序。
要按升序对地图进行排序,我们可以将顺序反转为 (x,y)->x.getKey().compareTo(y.getKey())
为了将结果合并回 LinkedHashMap,我们可以使用收集器 toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
Returns 一个将元素累积到 Map 中的 Collector,其键和值是将提供的映射函数应用于输入元素的结果。
工作代码
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));
要按升序排序,我可以使用:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
如何按降序排列?
您可以将任何您想要的比较器传递给 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
returns 是一个 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));
要倒序排序,将 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
));
Stream 具有接受比较器的 sorted
方法,因此您可以直接使用比较器作为 (x,y)->y.getKey().compareTo(x.getKey())
进行降序排序。
要按升序对地图进行排序,我们可以将顺序反转为 (x,y)->x.getKey().compareTo(y.getKey())
为了将结果合并回 LinkedHashMap,我们可以使用收集器 toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)
Returns 一个将元素累积到 Map 中的 Collector,其键和值是将提供的映射函数应用于输入元素的结果。
工作代码
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));