仅当存在可选项时如何应用条件?
How to apply a condition only if an optional is present?
我有一个 Optional<LocalDate>
对象和一个 Stream
其他日期。
Stream<LocalDate> dates = ...;
Optional<LocalDate> dateOptional = ...;
我想过滤掉可选日期之后的所有日期。如果可选的不存在,过滤器不应该做任何事情。
我是这样写Predicate
的:
Predicate<LocalDate> predicate = date -> !dateOptional.isPresent() || !date.isAfter(dateOptional.get());
Stream<LocalDate> filteredStream = dates.filter(predicate);
我想避免使用 isPresent()
和 get()
。有没有更实用的方法来编写相同的逻辑?我正在使用 Java 8.
重点是 Predicate<T>
必须 return 一个始终导致 boolean
的表达式。
因为 Localdate::isAfter
returns boolean
你可以使用 Predicate<LocalDate>
里面的 Optional
的优势,结果是 boolean
:
Optional<LocalDate> dateOptional = ...;
// Together Predicate<LocalDate>
Predicate<LocalDate> predicate = date -> dateOptional // .. Optional<LocalDate>
.map(d -> !date.isAfter(d)) // .. Optional<Boolean>
.orElse(true); // .. Boolean
Stream<LocalDate> filteredStream = dates.filter(predicate);
别忘了,Stream<LocalDate>
在终端操作之前一直保持打开状态。
编辑:感谢@Holger:整个predicate
可能会被优化以避免重复和不必要的调用:
Predicate<LocalDate> predicate = dateOptional // Optional<LocalDate>
.<Predicate<LocalDate>>map(d -> date -> !date.isAfter(d)) // Optional<Predicate<LocalDate>>
.orElse(date -> true); // Predicate<LocalDate>
我发现对于这样的问题,使用 LocalDate.MIN
几乎总是可以接受的,因为它会产生最简单、最易读的代码。
LocalDate date = getOptionalDate().orElse(LocalDate.MIN);
dateStream.filter(d -> !d.isAfter(date));
有一个轻微的边缘情况,如果您的流包含等于 LocalDate.MIN
的值,那么它会在不应该包含的时候被包含。鉴于 LocalDate.MIN
代表公元前约 1000 亿年,这种边缘情况对于所有意图和目的而言与大多数应用程序无关
我有一个 Optional<LocalDate>
对象和一个 Stream
其他日期。
Stream<LocalDate> dates = ...;
Optional<LocalDate> dateOptional = ...;
我想过滤掉可选日期之后的所有日期。如果可选的不存在,过滤器不应该做任何事情。
我是这样写Predicate
的:
Predicate<LocalDate> predicate = date -> !dateOptional.isPresent() || !date.isAfter(dateOptional.get());
Stream<LocalDate> filteredStream = dates.filter(predicate);
我想避免使用 isPresent()
和 get()
。有没有更实用的方法来编写相同的逻辑?我正在使用 Java 8.
重点是 Predicate<T>
必须 return 一个始终导致 boolean
的表达式。
因为 Localdate::isAfter
returns boolean
你可以使用 Predicate<LocalDate>
里面的 Optional
的优势,结果是 boolean
:
Optional<LocalDate> dateOptional = ...;
// Together Predicate<LocalDate>
Predicate<LocalDate> predicate = date -> dateOptional // .. Optional<LocalDate>
.map(d -> !date.isAfter(d)) // .. Optional<Boolean>
.orElse(true); // .. Boolean
Stream<LocalDate> filteredStream = dates.filter(predicate);
别忘了,Stream<LocalDate>
在终端操作之前一直保持打开状态。
编辑:感谢@Holger:整个predicate
可能会被优化以避免重复和不必要的调用:
Predicate<LocalDate> predicate = dateOptional // Optional<LocalDate>
.<Predicate<LocalDate>>map(d -> date -> !date.isAfter(d)) // Optional<Predicate<LocalDate>>
.orElse(date -> true); // Predicate<LocalDate>
我发现对于这样的问题,使用 LocalDate.MIN
几乎总是可以接受的,因为它会产生最简单、最易读的代码。
LocalDate date = getOptionalDate().orElse(LocalDate.MIN);
dateStream.filter(d -> !d.isAfter(date));
有一个轻微的边缘情况,如果您的流包含等于 LocalDate.MIN
的值,那么它会在不应该包含的时候被包含。鉴于 LocalDate.MIN
代表公元前约 1000 亿年,这种边缘情况对于所有意图和目的而言与大多数应用程序无关