使用流在列表中查找最大日期
一、概述
在本文中,我們將首先創建一個帶有日期的對象。然後,我們將看到如何使用Streams在這些對象的列表中找到最大日期。
2. 示例設置
Java 的原始Date API 仍然被廣泛使用,因此我們將展示一個使用它的示例。然而,從 Java 8 開始, LocalDate被引入,大多數Date方法都被棄用了。因此,我們還將展示一個使用LocalDate的示例。
首先,讓我們創建一個包含單獨Date屬性的基本Event對象:
public class Event {
Date date;
// constructor, getter and setter
}
我們現在可以定義三個Event的列表:今天發生的第一個,明天發生的第二個,以及一周內的第三個。要將日期添加到Date,我們將使用 Apache Commons 的DateUtils方法addDays() :
Date TODAY = new Date();
Event TODAYS_EVENT = new Event(TODAY);
Date TOMORROW = DateUtils.addDays(TODAY, 1);
Event TOMORROWS_EVENT = new Event(TOMORROW);
Date NEXT_WEEK = DateUtils.addDays(TODAY, 7);
Event NEXT_WEEK_EVENT = new Event(NEXT_WEEK);
List<Event> events = List.of(TODAYS_EVENT, TOMORROWS_EVENT, NEXT_WEEK_EVENT);
我們現在的目標是編寫一個能夠確定NEXT_WEEK_EVENT是此Event列表中的最大日期的方法。我們也會對LocalDate而不是Date做同樣的事情。我們的LocalEvent將如下所示:
public class LocalEvent {
LocalDate date;
// constructor, getter and setter
}
由於LocalDate已經有一個內置的plusDays()方法,因此構建Event列表更簡單一些:
LocalDate TODAY_LOCAL = LocalDate.now();
LocalEvent TODAY_LOCAL_EVENT = new LocalEvent(TODAY_LOCAL);
LocalDate TOMORROW_LOCAL = TODAY_LOCAL.plusDays(1);
LocalEvent TOMORROW_LOCAL_EVENT = new LocalEvent(TOMORROW_LOCAL);
LocalDate NEXT_WEEK_LOCAL = TODAY_LOCAL.plusWeeks(1);
LocalEvent NEXT_WEEK_LOCAL_EVENT = new LocalEvent(NEXT_WEEK_LOCAL);
List<LocalEvent> localEvents = List.of(TODAY_LOCAL_EVENT, TOMORROW_LOCAL_EVENT, NEXT_WEEK_LOCAL_EVENT);
3. 獲取最大日期
首先,我們將使用Stream API流式傳輸我們的Event列表。然後,我們需要將Date getter 應用於Stream的每個元素。因此,我們將獲得一個包含事件日期的Stream 。我們現在可以使用max()函數了。這將返回Stream中關於提供的Comparator的最大Date 。
Date類實現Comparable<Date> 。因此, compareTo()方法定義了自然日期順序。簡而言之,可以在max()中等效地調用以下兩個方法:
-
Date的compareTo()可以通過方法引用來引用 -
Comparator的naturalOrder()可以直接使用
最後,需要注意的是,如果給定的Event列表為 null 或為空,我們可以直接返回 null。這將確保我們在流式傳輸列表時不會遇到問題。
該方法最終如下所示:
Date findMaxDateOf(List<Event> events) {
if (events == null || events.isEmpty()) {
return null;
}
return events.stream()
.map(Event::getDate)
.max(Date::compareTo)
.get();
}
或者,使用naturalOrder(),它會顯示為:
Date findMaxDateOf(List<Event> events) {
if (events == null || events.isEmpty()) {
return null;
}
return events.stream()
.map(Event::getDate)
.max(Comparator.naturalOrder())
.get();
}
總而言之,我們現在可以快速測試我們的方法是否為我們的列表返回了正確的結果:
assertEquals(NEXT_WEEK, findMaxDateOf(List.of(TODAYS_EVENT, TOMORROWS_EVENT, NEXT_WEEK_EVENT);
使用LocalDate ,推理完全相同。 LocalDate確實實現了ChronoLocalDate接口,該接口擴展了Comparable<ChronoLocalDate> 。因此, LocalDate的自然順序由ChronoLocalDate的compareTo()方法定義。
結果,方法可以寫成:
LocalDate findMaxDateOf(List<LocalEvent> events) {
if (events == null || events.isEmpty()) {
return null;
}
return events.stream()
.map(LocalEvent::getDate)
.max(LocalDate::compareTo)
.get();
}
或者,以完全等效的方式:
LocalDate findMaxDateOf(List<LocalEvent> events) {
if (events == null || events.isEmpty()) {
return null;
}
return events.stream()
.map(LocalEvent::getDate)
.max(Comparator.naturalOrder())
.get();
}
我們可以編寫以下測試來確認它是否有效:
assertEquals(NEXT_WEEK_LOCAL, findMaxDateOf(List.of(TODAY_LOCAL_EVENT, TOMORROW_LOCAL_EVENT, NEXT_WEEK_LOCAL_EVENT)));
4。結論
在本教程中,我們了解瞭如何在對象列表中獲取最大日期。我們使用了Date和LocalDate對象。
與往常一樣,可以在 GitHub 上找到代碼。