我已经为这个问题做了很多研究,但是我没有找到一种方法来对自定义对象列表的Map(Map<String, List<CustomObj>>
)进行排序。排序依据是基于CustomObj属性(如SORT_BY_NAME,SORT_BY_DATE等)进行比较。
一个激励我的例子是:
- 我有一个自定义对象:
Person
(具有名称、出生日期等属性); - 我有一个
Person
对象List
的Map
,如下所示:Map<String, List<Person>>
。映射键用于其他目的; - 我想创建一个比较器和排序方法,根据
Person
对象的属性(名称、日期等)进行升序排序映射。
为简单起见,我报告了真实代码,但将其适应了一个简化的Person
对象案例,因为它已经代表了实体的概念。
Person.java
-> 自定义对象
public class Person {
private String name;
private Date dateOfBirth;
...
// Empty and Full attrs Constructors
...
// Getter and Setter
...
// Comparator by name
public static Comparator<Person> COMPARE_BY_NAME = Comparator.comparing(one -> one.name);
// Comparator by date
public static Comparator<Person> COMPARE_BY_DATE = Comparator.comparing(one -> one.dateOfBirth);
}
Sorter.java
-> 排序器对象
public class Sorter {
// List Comparator of Person by Date
public static final Comparator<? super List<Person>> COMPARATOR_BY_DATE = (Comparator<List<Person>>) (p1, p2) -> {
for (Persontab person1: p1) {
for (Person person2: p2) {
return Person.COMPARE_BY_DATE.compare(person1, person2);
}
}
return 0;
};
// List Comparator of Person by Name
public static final Comparator<? super List<Person>> COMPARATOR_BY_NAME = (Comparator<List<Person>>) (p1, p2) -> {
for (Persontab person1: p1) {
for (Person person2: p2) {
return Person.COMPARE_BY_NAME.compare(person1, person2);
}
}
return 0;
};
// Sorting method
public Map<String, List<Person>> sort(Map<String, List<Person>> map, Comparator<? super List<Person>> comparator) {
return map.entrySet()
.stream()
.sorted(Map.Entry.comparingByValue(comparator))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (v1, v2) -> v1, LinkedHashMap::new));
}
}
Main.java
-> 开始代码
public class MainApp {
public static void main(String[] args) {
Map<String, List<Person>> exampleMap = new HashMap<>();
List<Person> personList = new ArrayList<>();
personList.add(new Person("name1", new Date("2022-01-01")));
personList.add(new Person("name12", new Date("2022-01-05")));
personList.add(new Person("name13", new Date("2022-01-03")));
map.put("2022-01", personList);
personList.clear();
personList.add(new Person("name14", new Date("2021-02-01")));
personList.add(new Person("name3", new Date("2021-02-05")));
personList.add(new Person("name4", new Date("2021-02-03")));
map.put("2021-02", personList);
Sorter sorter = new Sorter();
// Example of sorting by date
map = sorter.sort(exampleMap, Sorter.COMPARATOR_BY_DATE);
// In this case the sorting works correctly, or rather it sorts the items by date as I expect
// Example of sorting by name
map = sorter.sort(exampleMap, Sorter.COMPARATOR_BY_NAME);
// In this case, I don't think sorting works correctly. Sort each list of elements for each key in ascending order. But it doesn't sort the map elements.
/* I expect to have the following map when sort by date:
"2021-02": [
Person("name14", new Date("2021-02-01")),
Person("name4", new Date("2021-02-03")),
Person("name3", new Date("2021-02-05"))
],
"2022-01": [
Person("name14", new Date("2021-02-01")),
Person("name13", new Date("2022-01-03")),
Person("name12", new Date("2022-01-05"))
]
}
}
HashMap
进行排序。这是它的基本属性之一,即它没有任何顺序。如果你需要一种排序方式,可以使用TreeMap
,它按键进行排序,或者使用LinkedHashMap
,它按插入顺序排序。 - ThomasLinkedHashMap
排序映射条目?还是两者都要排序? - Thomasmap(list -> new ArrayList<>(list))
来创建副本,并使用peek(list-> Collections.sort(list, comparator))
来对每个列表进行排序,然后应用流排序和收集。 - Thomas