我的問題是如何Map根據其值和鍵對內容進行排序并獲得一個List條目作為結果?
首先,條目需要按值按降序排序,然后如果值發生沖突,也按鍵按降序對它們進行排序。
給定的示例Map:
Map<String,Integer> data = new HashMap();
data.put("a",10);
data.put("b",3);
data.put("c",10);
預期順序:
["c", 10], ["a",10], ["b",3]
uj5u.com熱心網友回復:
為此,您需要定義一個Comparator.
為此,您可以使用作為Java 8的增強功能添加到Comparator和Map.Entry介面的靜態方法。
介面的方法comparingByValue()和方法都將分別為值和鍵生成一個比較器。為了獲得降序方法,需要對它們應用。comparingByKey()Map.Entry 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);
有關如何使用 Java 8 方法構建比較器的更多資訊,請查看本教程
下一步是創建一個排序的條目串列。
為此,您可以通過將條目集傳遞給建構式然后在其上應用方法來List手動創建條目,或者通過使用Stream APIsort()
為了用流實作它,首先,我們需要獲取一個條目流。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]
uj5u.com熱心網友回復:
使用流 api 和 custom 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()));
}
}
}
}
uj5u.com熱心網友回復:
Comparator<Map.Entry<String,Integer>>根據您的規則撰寫一個比較地圖條目的代碼。獲取地圖之外的條目串列new ArrayList<>(map.entrySet())。使用 對該串列進行排序Collections.sort(list, comparator)。
uj5u.com熱心網友回復:
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}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/448475.html
上一篇:找到最小值的排序演算法的名稱是什么,將其添加到結果中并將其從原始串列中洗掉
下一篇:按R中的自定義函式排序
