使用流在列表中查找最大日期
一、概述
在本文中,我們將首先創建一個帶有日期的對象。然後,我們將看到如何使用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 上找到代碼。