簡體   English   中英

Java - 過濾以獲取日期列表中幾個月的最后一天(不是日歷的最后一天)

[英]Java - Filter to get Last Day of several months in a list of dates (not calendar last day)

查詢:過濾以下數據以獲取列表中每個月的最后日期。 請注意,數據中的最后一個月日期可能與日歷月的最后日期匹配,也可能不匹配。 預期的 output 顯示在第二個列表中。

研究:

  • 我相信 TemporalAdjusters.lastDayOfMonth() 在這種情況下無濟於事,因為最后日期可能與日歷月的最后日期匹配,也可能不匹配
  • 我在這個論壇和谷歌上檢查了幾個主題,但找不到與我需要類似的東西

希望問題很清楚,並為我指明如何使用 Streams 完成此操作,因為我不想使用 For 循環。

樣本數據:

樣本數據

需要 Output:

需要輸出

執行此操作的預期方法是按月 + 年分組,然后找到每個組的最大日期:

DateFormatter formatter = DateFormatter.forPattern("MMMM yyyy");

List<Data> lastDays = data.stream()
      .collect(Collectors.toMap(d -> formatter.format(d.getDate()), Function.identity(),
          BinaryOperator.maxBy(Comparator.comparing(Data::getDate))))
      .values().stream().collect(Collectors.toList());
 class Data{
     LocalDate date;
     String model;
     //...
 }

我建議創建一個Map<YearMonth, List<LocalDate>並解析您的所有日期並填寫您的 map。 之后,您對所有列表進行排序,每個列表中的最后一個(或第一個取決於排序順序)值將是您想要的值

好吧, groupingBymaxBy的組合可能就可以了。

我希望您的表是Event類型:

record Event(LocalDate date, String model, int start, int end) { }

要獲取表中該月的最后幾天,我們可以使用groupingBy 為了對其進行分組,我們可以首先創建一個分組類型。 下面,我創建了一個EventGrouping記錄,使用static方法將Event轉換為EventGrouping 您想要的 output 建議您按每個年月模型組合進行分組,因此我們只選擇了這兩個屬性:

public record EventGrouping(YearMonth yearMonth, String model) {
        
    public static EventGrouping fromEvent(Event event) {
        return new EventGrouping(YearMonth.from(event.date()), event.model());
    }
}

然后,我們可以得到我們想要的結果,如下所示:

events.stream()
    .collect(Collectors.groupingBy(
        EventGrouping::fromEvent,
        Collectors.maxBy(Comparator.comparing(Event::date))
    ));

這里發生的是所有 stream 元素都按我們的EventGrouping分組,然后選擇每個事件組的“最大值”。 當然,最大值是該特定月份的最近日期。

請注意,對於組為空的情況, maxBy返回一個Optional 另請注意,生成的Map是無序的。

我們可以分別使用collectingAndThenmap 工廠來解決這兩個問題:

Map<EventGrouping, Event> map = events.stream()
    .collect(groupingBy(
        EventGrouping::fromEvent,
        () -> new TreeMap<>(Comparator.comparing(EventGrouping::yearMonth)
            .thenComparing(EventGrouping::model)),
        collectingAndThen(maxBy(Comparator.comparing(Event::date)), Optional::get)
    ));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM