Java獲取兩個日期中間的所有日期及Stream類,Lambda表達式使用
一、獲取兩個日期之間的所有日期
private static final String FORMAT = "yyyyMMdd";
public List<String> getDates(String start, String end) {
List<String> dates = new ArrayList<>();
LocalDate startDate = LocalDate.parse(start, DateTimeFormatter.ofPattern(FORMAT)).plusDays(1);
LocalDate endDate = LocalDate.parse(end, DateTimeFormatter.ofPattern(FORMAT));
long dex = ChronoUnit.DAYS.between(startDate, endDate);
if (dex > 0) {
Stream.iterate(startDate, d -> d.plusDays(1)).limit(dex + 1).forEach(f -> dates.add(f.format(DateTimeFormatter.ofPattern(FORMAT))));
}
return dates;
}
二、Stream使用
上面代碼,我們用到了Stream.iterate、Stream.limit、Stream.forEach
iterate
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
如jdk8中定義,iterate方法返回一個流,第一個參數爲啓示元素,第二個參數爲UnaryOperator(UnaryOperator繼承Function,功能是對數據進行操作,生成一個同類型對象)
回到我們要實現的功能,從startDate開始,每天加1,使用iterate方法,代碼爲:
Stream.iterate(startDate, new UnaryOperator<LocalDate>() {
@Override
public LocalDate apply(LocalDate localDate) {
return localDate.plusDays(1);
}
})
limit
Stream<T> limit(long maxSize);
如jdk8中定義,limit方法返回一個流,參數maxSize表示該流的元素個數限制。
回到我們要實現的功能,從startDate開始,每天加1,且小於等於endDate (數組元素爲dex+1個):
Stream.iterate(startDate, new UnaryOperator<LocalDate>() {
@Override
public LocalDate apply(LocalDate localDate) {
return localDate.plusDays(1);
}
}).limit(dex + 1)
forEach
void forEach(Consumer<? super T> action);
forEach對流進行遍歷,接收Consumer類型參數
Consumer的作用顧名思義,是給定義一個參數,對其進行(消費)處理,處理的方式可以是任意操作。
兩個核心方法:
- void accept(T t) ; // 對給定的參數T執行定義的操作
- default Consumer andThen(Consumer<? super T> after); //對給定的參數T執行定義的操作執行再繼續執行after定義的操作
回到我們要實現的功能,從startDate開始,每天加1,且小於等於endDate (數組元素爲dex+1個),並且將這些日期放到list中:
Stream.iterate(startDate, new UnaryOperator<LocalDate>() {
@Override
public LocalDate apply(LocalDate localDate) {
return localDate.plusDays(1);
}
}).limit(dex + 1).forEach(new Consumer<LocalDate>() {
@Override
public void accept(LocalDate localDate) {
dates.add(localDate.toString());
}
});
三、lambda表達式
以上,我們的需求是實現了,但代碼看着比較繁瑣。使用lambda可大大簡化代碼。
Lambda 表達式,也可稱爲閉包,它允許把函數作爲一個方法的參數 。
// lambda 表達式的語法格式
(parameters) -> expression
或
(parameters) ->{ statements; }
lambda表達式的重要特徵:
- 可選類型聲明:不需要聲明參數類型,編譯器可以統一識別參數值。
- 可選的參數圓括號:一個參數無需定義圓括號,但多個參數需要定義圓括號。
- 可選的大括號:如果主體包含了一個語句,就不需要使用大括號。
- 可選的返回關鍵字:如果主體只有一個表達式返回值則編譯器會自動返回值,大括號需要指定明表達式返回了一個數值。
Stream.iterate(startDate, new UnaryOperator<LocalDate>() {
@Override
public LocalDate apply(LocalDate localDate) {
return localDate.plusDays(1);
}
})
按照上面的lambda語法,我們改造如上代碼爲,
Stream.iterate(startDate, (d) -> {return d.plusDays(1);})
// 按照lambda表達式的特性,可以簡寫成如下
Stream.iterate(startDate, d -> d.plusDays(1))
[1] https://www.runoob.com/java/java8-lambda-expressions.html