[英]Can't figure out how to print a list in this correct order
基本上,我有一個對象的數組列表,這些對象具有名稱和startDate,並且它們的初始順序類似於:
弗蘭克1990年10月20日
1990年1月2日的法案
弗蘭克2/2/1990
約翰1990年9月8日
1990年4月4日法案
弗蘭克1990年5月1日
我試圖按聲明的名字順序打印,然后按日期打印,例如,最終打印應打印:
弗蘭克1990年1月1日
弗蘭克1990年5月1日
弗蘭克1990年10月20日
1990年1月2日的法案
1990年4月4日法案
約翰1990年9月8日
假設您的對象類如下所示:
private static class MyObject {
private final String name;
private final Date date;
private MyObject(String name, Date date) {
this.name = name;
this.date = date;
}
public String getName() {
return name;
}
public Date getDate() {
return date;
}
}
您可以使用以下方法打印對象:
@Test
public void printInOrder() {
List<MyObject> list = new ArrayList<>(); // List containing your objects
list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 10, 20).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 1, 2).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 2, 2).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("John", Date.from(LocalDate.of(1990, 9, 8).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 4, 4).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 5, 1).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.stream()
.sorted(Comparator.comparing(MyObject::getName)
.thenComparing(Comparator.comparing(MyObject::getDate)))
.map(obj -> obj.getName() + " " + obj.getDate())
.forEach(System.out::println);
}
輸出:
1990年1月2日星期二00:00:00 CET
1990年4月4日星期三00:00:00比爾
1990年2月2日星期五星期五歐洲中部時間
1990年5月1日美國東部時間00:00:00
1990年10月20日星期六星期六09:00:00 CET
John Sat 1990年9月8日00:00:00
它使用Java 8流和比較器鏈對對象進行排序。 比較器按給定的屬性進行比較, thenComparing
使用thenComparing
鏈接它們。
更新:
由於不確定我是否可能誤解了您,因此以下情況的第二個版本:
您想按名稱排序,但是名稱會按順序出現在原始列表中 ,因此名稱將首先出現。
在這種情況下,您將必須記住一個單獨的臨時列表中的名稱順序(僅按原始順序包含唯一名稱),之后可以在比較器中使用它們。
通過將原始列表轉換為一個集合(因此只有唯一的名稱),然后將該集合轉換回一個列表(以便能夠在比較器中使用indexOf
)來生成此列表。
@Test
public void printInOrder() {
List<MyObject> list = new ArrayList<>();
list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 10, 20).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 1, 2).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 2, 2).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("John", Date.from(LocalDate.of(1990, 9, 8).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Bill", Date.from(LocalDate.of(1990, 4, 4).atStartOfDay(ZoneId.systemDefault()).toInstant())));
list.add(new MyObject("Frank", Date.from(LocalDate.of(1990, 5, 1).atStartOfDay(ZoneId.systemDefault()).toInstant())));
List<String> declaredNameOrder = new ArrayList<>(list.stream()
.map(MyObject::getName)
.collect(Collectors.toCollection(LinkedHashSet::new)));
list.stream()
.sorted(Comparator.<MyObject>comparingInt(o -> declaredNameOrder.indexOf(o.getName()))
.thenComparing(Comparator.comparing(MyObject::getDate)))
.map(obj -> obj.getName() + " " + obj.getDate())
.forEach(System.out::println);
}
輸出:
1990年2月2日星期五星期五歐洲中部時間
1990年5月1日美國東部時間00:00:00
1990年10月20日星期六星期六09:00:00 CET
1990年1月2日星期二00:00:00 CET
1990年4月4日星期三00:00:00比爾
John Sat 1990年9月8日00:00:00
您應該分兩個步驟進行操作:
使用自定義比較器按名稱排序,例如:
Collections.sort(myList, new Comparator<MyObject>() {
public int compare(MyObject o1, MyObject o2) {
return o1.getName().compareTo(o2.getName());
}
});
並將輸出存儲在臨時列表中
第二次使用臨時列表按數據排序:
Collections.sort(myList, new Comparator<MyObject>() {
public int compare(MyObject o1, MyObject o2) {
return o1.getDate().compareTo(o2.getDate());
}
});
然后您的列表將按照您的意願進行排序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.