使用 Stream API 遍历 LocalDate
Iterate through LocalDate wth Stream API
我有三个 LocalDates(最后 3 天),对于每个日期我都想循环并执行一些操作:
StringBuilder result = "";
for (LocalDate currentDate = LocalDate.now(); currentDate.isAfter(LocalDate.now().minusDays(3)); currentDate = currentDate.minusDays(1)){
Page<User> users = userService.getAllUsersByRegistrationDate(currentDate);
String reportTable = reportService.getReportTable(users, tableTemplate);
result.append(reportTable);
}
如何用 Stream 替换此代码 API 或提高可读性?
Java8个解
如果你真的坚持使用 java-8,你所能做的就是使用你想要过去的那么多天的 IntStream
创建一个 LocalDate
的序列.然后mapToObj
创建一个相关的LocalDate
.
LocalDate currentDate = LocalDate.now();
String result = IntStream.range(0, 3)
.mapToObj(currentDate::minusDays)
.map(date -> {
Page<User> users = userService.getAllUsersByRegistrationDate(date);
return reportService.getReportTable(users, tableTemplate);
})
.collect(Collectors.joining());
Java 9+ 解决方案
如果您使用 java-9 或更高版本,您可以利用无限流的优势并不断生成项目,直到满足特定条件。
Three-args Stream.iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
LocalDate threeDaysAgo = currentDate.minusDays(3);
String result = Stream.iterate(
LocalDate.now(),
date -> date.isAfter(threeDaysAgo),
date -> date.minusDays(1))
.map(date -> {
Page<User> users = userService.getAllUsersByRegistrationDate(date);
return reportService.getReportTable(users, tableTemplate);
})
.collect(Collectors.joining());
新方法Stream::takeWhile(Predicate<? super T> predicate)
LocalDate threeDaysAgo = currentDate.minusDays(3);
String result = Stream.iterate(LocalDate.now(), date -> date.minusDays(1))
.takeWhile(date -> date.isAfter(threeDaysAgo))
.map(date -> {
Page<User> users = userService.getAllUsersByRegistrationDate(date);
return reportService.getReportTable(users, tableTemplate);
})
.collect(Collectors.joining());
以上所有示例生成 3 个 LocalDate
个实例,因为今天是 2020-10-15
,过去 3 天它们将具有:2020-10-15
、2020-10-14
、2020-10-13
并通过 Stream<LocalDate>
.
提供它们以供进一步处理
免责声明:我发现 for-loop 更具可读性。不要指望将 for-loop“转换”为 Stream API 会自动增加可读性和简洁性。在很多情况下,事实并非如此。
LocalDate.datesUntil(本地日期,期间)
我觉得你的代码在我看来很好。如果你想使用流操作,或者你只是好奇它的外观,因为 Java 9 你可以这样做:
LocalDate today = LocalDate.now(ZoneId.of("Africa/Timbuktu"));
today.datesUntil(today.minusDays(3), Period.ofDays(-1))
.forEach(ld -> {
System.out.println("Now doing something with date " + ld);
});
刚才运行时输出:
Now doing something with date 2020-10-15
Now doing something with date 2020-10-14
Now doing something with date 2020-10-13
LocalDate.datesUntil()
与负周期一起工作的记录不多,但确实如此 returns LocalDate
对象流。
(我知道在这种情况下 lambda 中的花括号是不必要的,但从你的问题看来你想为每个日期做一个以上的语句,所以它们当然是必要的。如果你那里只需要一个方法调用,您可能只需要一行。.forEach(ld -> System.out.println("Now doing something with date " + ld))
.)
文档 link:LocalDate.datesUntil()
我有三个 LocalDates(最后 3 天),对于每个日期我都想循环并执行一些操作:
StringBuilder result = "";
for (LocalDate currentDate = LocalDate.now(); currentDate.isAfter(LocalDate.now().minusDays(3)); currentDate = currentDate.minusDays(1)){
Page<User> users = userService.getAllUsersByRegistrationDate(currentDate);
String reportTable = reportService.getReportTable(users, tableTemplate);
result.append(reportTable);
}
如何用 Stream 替换此代码 API 或提高可读性?
Java8个解
如果你真的坚持使用 java-8,你所能做的就是使用你想要过去的那么多天的 IntStream
创建一个 LocalDate
的序列.然后mapToObj
创建一个相关的LocalDate
.
LocalDate currentDate = LocalDate.now();
String result = IntStream.range(0, 3)
.mapToObj(currentDate::minusDays)
.map(date -> {
Page<User> users = userService.getAllUsersByRegistrationDate(date);
return reportService.getReportTable(users, tableTemplate);
})
.collect(Collectors.joining());
Java 9+ 解决方案
如果您使用 java-9 或更高版本,您可以利用无限流的优势并不断生成项目,直到满足特定条件。
Three-args Stream.iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
LocalDate threeDaysAgo = currentDate.minusDays(3);
String result = Stream.iterate(
LocalDate.now(),
date -> date.isAfter(threeDaysAgo),
date -> date.minusDays(1))
.map(date -> {
Page<User> users = userService.getAllUsersByRegistrationDate(date);
return reportService.getReportTable(users, tableTemplate);
})
.collect(Collectors.joining());
新方法Stream::takeWhile(Predicate<? super T> predicate)
LocalDate threeDaysAgo = currentDate.minusDays(3);
String result = Stream.iterate(LocalDate.now(), date -> date.minusDays(1))
.takeWhile(date -> date.isAfter(threeDaysAgo))
.map(date -> {
Page<User> users = userService.getAllUsersByRegistrationDate(date);
return reportService.getReportTable(users, tableTemplate);
})
.collect(Collectors.joining());
以上所有示例生成 3 个 LocalDate
个实例,因为今天是 2020-10-15
,过去 3 天它们将具有:2020-10-15
、2020-10-14
、2020-10-13
并通过 Stream<LocalDate>
.
免责声明:我发现 for-loop 更具可读性。不要指望将 for-loop“转换”为 Stream API 会自动增加可读性和简洁性。在很多情况下,事实并非如此。
LocalDate.datesUntil(本地日期,期间)
我觉得你的代码在我看来很好。如果你想使用流操作,或者你只是好奇它的外观,因为 Java 9 你可以这样做:
LocalDate today = LocalDate.now(ZoneId.of("Africa/Timbuktu"));
today.datesUntil(today.minusDays(3), Period.ofDays(-1))
.forEach(ld -> {
System.out.println("Now doing something with date " + ld);
});
刚才运行时输出:
Now doing something with date 2020-10-15 Now doing something with date 2020-10-14 Now doing something with date 2020-10-13
LocalDate.datesUntil()
与负周期一起工作的记录不多,但确实如此 returns LocalDate
对象流。
(我知道在这种情况下 lambda 中的花括号是不必要的,但从你的问题看来你想为每个日期做一个以上的语句,所以它们当然是必要的。如果你那里只需要一个方法调用,您可能只需要一行。.forEach(ld -> System.out.println("Now doing something with date " + ld))
.)
文档 link:LocalDate.datesUntil()