我的问题是如何根据Map
内容的值和键对其进行排序,从而得到条目的List
?
首先,需要按照值按降序对条目进行排序,然后如果值发生冲突,还需要按照降序中的键对它们进行排序。
给定的示例:
Map<String,Integer> data = new HashMap();
data.put("a",10);
data.put("b",3);
data.put("c",10);
期望顺序:
["c", 10], ["a",10], ["b",3]
发布于 2022-03-22 06:46:41
public class Person implements Comparable<Person>{
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person person) {
if(this.age!= person.age){
return person.age.compareTo(this.age);
} else {
return person.name.compareTo(this.name);
}
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public static void main(String argsp[]){
Map<String,Integer> data = new HashMap();
data.put("a",10);
data.put("b",3);
data.put("c",10);
List<Person> collect = data.entrySet().stream().map(entry -> new Person(entry.getKey(), entry.getValue())).collect(Collectors.toList());
Collections.sort(collect);
collect.stream().forEach(person-> System.out.println(person));
Collection<Map.Entry<String,Integer>> result = collect.stream().map(person ->
new AbstractMap.SimpleEntry<String, Integer>(person.name, person.age)).collect(Collectors.toList());
}
}
结果:
Person{name='c', age=10}
Person{name='a', age=10}
Person{name='b', age=3}
发布于 2022-03-22 08:45:17
为此,需要定义一个Comparator
。
为此,您可以使用静态方法,这些方法是作为、Java 8的增强添加到Comparator
和Map.Entry
接口中的。
comparingByValue()
和Map.Entry
接口的comparingByKey()
两种方法都将分别为值和键生成比较器。为了得到一个降阶方法,需要对其应用reversed()
方法。
两个比较器都与thenComparing()
方法链接在一起。
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
Map.Entry.<String, Integer>comparingByValue().reversed()
.thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());
请注意,编译器是,无法根据比较器的结果类型推断comparingByValue()
和comparingByKey()
的正确参数类型,只能基于的。
因此,comparingByValue()
和comparingByKey()
都需要显式地提供泛型类型信息<String, Integer>
(键和值的类型)。
如果一开始看起来太难理解,您可能会将它分成几行(在本例中,类型推断工作得很好):
Comparator<Map.Entry<String, Integer>> byValDesc =
Map.Entry.comparingByValue().reversed();
Comparator<Map.Entry<String, Integer>> byKeyDesc =
Map.Entry.comparingByKey().reversed();
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
byValDesc.thenComparing(byKeyDesc);
下一步是创建一个排序的条目列表。
为此,您可以通过将条目集传递给构造函数来手动创建条目的List
,然后在其上应用sort()
方法,或者使用Stream
为了用流来实现它,首先,我们需要获得一个条目流。通过传递给定的比较器执行sorting()
操作,并通过应用终端操作collect()
将结果收集到列表中。
public static List<Map.Entry<String, Integer>> getMapEntryList(Map<String,Integer> data,
Comparator<Map.Entry<String, Integer>> comparator) {
return data.entrySet().stream()
.sorted(comparator)
.collect(Collectors.toList());
}
main()
public static void main(String[] args) {
Map<String,Integer> data = Map.of("a",10, "b",3,"c",10);
Comparator<Map.Entry<String, Integer>> valDescThenKeyDesc =
Map.Entry.<String, Integer>comparingByValue().reversed()
.thenComparing(Map.Entry.<String, Integer>comparingByKey().reversed());
List<Map.Entry<String, Integer>> result = getMapEntryList(data, valDescThenKeyDesc);
System.out.println(result);
}
输出
[c=10, a=10, b=3]
发布于 2022-03-22 06:54:29
使用流api和自定义Comparator
。
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
static Map<String, Integer> createTestMap() {
Map<String, Integer> data = new HashMap();
data.put("a", 10);
data.put("b", 3);
data.put("c", 10);
return data;
}
public static void main(String[] args) {
var sorted = createTestMap().entrySet().stream()
.sorted(Comparator
.comparing(Map.Entry<String, Integer>::getValue)
.thenComparing(Map.Entry<String, Integer>::getKey).reversed())
.collect(Collectors.toList());
for (var kv : sorted) {
System.out.println(
String.format("%s\t%s", kv.getKey(), kv.getValue()));
}
}
}
}
https://stackoverflow.com/questions/71573763
复制相似问题