如何替换流的 while 循环或 Flux 以迭代我的元素
How to replace a while loop for a stream or a Flux to iterate my elements
我有这个代码
public String calculateShippingEstimateDate(LocalDateTime initialDate, Integer totalDaysToAdd, SaveOrderSourceData saveOrderSourceData) {
int workDays = totalDaysToAdd;
LocalDateTime finalDate = LocalDateTime.of(initialDate.getYear(),
initialDate.getMonth(),
initialDate.getDayOfMonth(),
initialDate.getHour(),
initialDate.getMinute(),
initialDate.getSecond());
while (workDays > 0) {
finalDate = finalDate.plusDays(1);
if (!(
DateUtility.isWeekend(finalDate.getDayOfWeek())
|| checkHolidays(saveOrderSourceData, finalDate)
)) {
workDays--;
}
}
return finalDate.toString();
}
private boolean checkHolidays(SaveOrderSourceData saveOrderSourceData, LocalDateTime finalDate) {
return saveOrderSourceData.getHolidays()
.stream().anyMatch(holiday -> getHoliday(holiday).isEqual(finalDate.toLocalDate()));
}
private LocalDate getHoliday(Holiday holiday){
return LocalDate.of(holiday.getYear(),holiday.getMonth(), holiday.getDay());
}
重要的是要知道此示例的估计日期等于初始日期后五天。
我们有一个 initialDate(15/02/2022) 等于 finalDate。
我们进入 while 循环,它验证工作日(在本次迭代中为 5)是否为 0,为假,因此 finalDate 增加其值,并验证日期(16/02/2022)是周末或假期,依此类推,当 finalDate 等于 (19/02/2022) 时,它不会减少 workDays 的值。最后,当 finalDate 为 (21/02/2022) workDays 等于 0,且 finalDate 为星期一时,while 循环结束。
假期Class
import lombok.Builder;
import lombok.Data;
@Data
@Builder(toBuilder = true)
public class Holiday {
private final String id;
private final int year;
private final int month;
private final int day;
}
DateUtility Class
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import static java.time.DayOfWeek.SATURDAY;
import static java.time.DayOfWeek.SUNDAY;
public class DateUtility {
private DateUtility() {
}
public static boolean isWeekend(DayOfWeek dayOfWeek) {
return SATURDAY.equals(dayOfWeek)
|| SUNDAY.equals(dayOfWeek);
}
}
SaveOrderSourceDataclass
@Data
@Builder(toBuilder = true)
public class SaveOrderSourceData {
private final List<Holiday> holidays;
}
这将等同于您的 while
循环。
iterate()
将 initialDate.plusDays(1)
作为种子,并根据 UnaryOperator date -> date.plusDays(1)
; 生成新元素
filter()
- 在流中只生活工作日(假设 DateUtility
和 checkHolidays()
正确地完成工作);
limit()
- 顾名思义,将流中的元素数量限制为给定值(注意,过滤掉周末或假期时应用 limit()
);
max()
- 生成可选结果,可选结果可能为空 initialDate
并且给定范围内的所有其他日期为周末或假期,在这种情况下流将为空;
map()
- 如果值存在则应用于可选;
orElse()
- 提供替代值(以及在您的实现中,如果没有找到进一步的日期,它将 return initialDate
)。
public String calculateShippingEstimateDate(LocalDateTime initialDate,
Integer totalDaysToAdd,
SaveOrderSourceData saveOrderSourceData) {
return Stream.iterate(initialDate.plusDays(1), date -> date.plusDays(1))
.filter(date -> !(DateUtility.isWeekend(date.getDayOfWeek())
|| checkHolidays(saveOrderSourceData, date)))
.limit(totalDaysToAdd)
.max(Comparator.naturalOrder())
.map(LocalDateTime::toString)
.orElse(initialDate.toString());
}
我已经使用您的实用程序测试了此解决方案 类 它产生与您的命令式实施相同的结果
public static void main(String[] args) {
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 5, SaveOrderSourceData.builder().holidays(List.<Holiday>of()).build()));
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 5, SaveOrderSourceData.builder().holidays(List.<Holiday>of()).build()) + "\n");
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 27, SaveOrderSourceData.builder().holidays(List.of(Holiday.builder().id("id1").year(2022).month(3).day(3).build())).build()));
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 27, SaveOrderSourceData.builder().holidays(List.of(Holiday.builder().id("id1").year(2022).month(3).day(3).build())).build()));
}
输出
2022-02-22T21:43:25
2022-02-22T21:43:25
2022-03-25T21:43:25
2022-03-25T21:43:25
我有这个代码
public String calculateShippingEstimateDate(LocalDateTime initialDate, Integer totalDaysToAdd, SaveOrderSourceData saveOrderSourceData) {
int workDays = totalDaysToAdd;
LocalDateTime finalDate = LocalDateTime.of(initialDate.getYear(),
initialDate.getMonth(),
initialDate.getDayOfMonth(),
initialDate.getHour(),
initialDate.getMinute(),
initialDate.getSecond());
while (workDays > 0) {
finalDate = finalDate.plusDays(1);
if (!(
DateUtility.isWeekend(finalDate.getDayOfWeek())
|| checkHolidays(saveOrderSourceData, finalDate)
)) {
workDays--;
}
}
return finalDate.toString();
}
private boolean checkHolidays(SaveOrderSourceData saveOrderSourceData, LocalDateTime finalDate) {
return saveOrderSourceData.getHolidays()
.stream().anyMatch(holiday -> getHoliday(holiday).isEqual(finalDate.toLocalDate()));
}
private LocalDate getHoliday(Holiday holiday){
return LocalDate.of(holiday.getYear(),holiday.getMonth(), holiday.getDay());
}
重要的是要知道此示例的估计日期等于初始日期后五天。
我们有一个 initialDate(15/02/2022) 等于 finalDate。
我们进入 while 循环,它验证工作日(在本次迭代中为 5)是否为 0,为假,因此 finalDate 增加其值,并验证日期(16/02/2022)是周末或假期,依此类推,当 finalDate 等于 (19/02/2022) 时,它不会减少 workDays 的值。最后,当 finalDate 为 (21/02/2022) workDays 等于 0,且 finalDate 为星期一时,while 循环结束。
假期Class
import lombok.Builder;
import lombok.Data;
@Data
@Builder(toBuilder = true)
public class Holiday {
private final String id;
private final int year;
private final int month;
private final int day;
}
DateUtility Class
import java.time.DayOfWeek;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import static java.time.DayOfWeek.SATURDAY;
import static java.time.DayOfWeek.SUNDAY;
public class DateUtility {
private DateUtility() {
}
public static boolean isWeekend(DayOfWeek dayOfWeek) {
return SATURDAY.equals(dayOfWeek)
|| SUNDAY.equals(dayOfWeek);
}
}
SaveOrderSourceDataclass
@Data
@Builder(toBuilder = true)
public class SaveOrderSourceData {
private final List<Holiday> holidays;
}
这将等同于您的 while
循环。
iterate()
将initialDate.plusDays(1)
作为种子,并根据 UnaryOperatordate -> date.plusDays(1)
; 生成新元素
filter()
- 在流中只生活工作日(假设DateUtility
和checkHolidays()
正确地完成工作);limit()
- 顾名思义,将流中的元素数量限制为给定值(注意,过滤掉周末或假期时应用limit()
);max()
- 生成可选结果,可选结果可能为空initialDate
并且给定范围内的所有其他日期为周末或假期,在这种情况下流将为空;map()
- 如果值存在则应用于可选;orElse()
- 提供替代值(以及在您的实现中,如果没有找到进一步的日期,它将 returninitialDate
)。
public String calculateShippingEstimateDate(LocalDateTime initialDate,
Integer totalDaysToAdd,
SaveOrderSourceData saveOrderSourceData) {
return Stream.iterate(initialDate.plusDays(1), date -> date.plusDays(1))
.filter(date -> !(DateUtility.isWeekend(date.getDayOfWeek())
|| checkHolidays(saveOrderSourceData, date)))
.limit(totalDaysToAdd)
.max(Comparator.naturalOrder())
.map(LocalDateTime::toString)
.orElse(initialDate.toString());
}
我已经使用您的实用程序测试了此解决方案 类 它产生与您的命令式实施相同的结果
public static void main(String[] args) {
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 5, SaveOrderSourceData.builder().holidays(List.<Holiday>of()).build()));
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 5, SaveOrderSourceData.builder().holidays(List.<Holiday>of()).build()) + "\n");
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 27, SaveOrderSourceData.builder().holidays(List.of(Holiday.builder().id("id1").year(2022).month(3).day(3).build())).build()));
System.out.println(new LDTUtil().getShippingDateLoop(LocalDateTime.now(), 27, SaveOrderSourceData.builder().holidays(List.of(Holiday.builder().id("id1").year(2022).month(3).day(3).build())).build()));
}
输出
2022-02-22T21:43:25
2022-02-22T21:43:25
2022-03-25T21:43:25
2022-03-25T21:43:25