Optional<T> 不处理空元素

Optional<T> does not handle null elements

正如我所试验的那样,Optional<T> 不处理 null 元素,因此在下面的示例中它会在最后一个语句中抛出 NullPointerException

List<String> data = Arrays.asList("Foo", null, "Bar");
data.stream().findFirst().ifPresent(System.out::println);
data.stream().skip(1).findFirst().ifPresent(System.out::println);

所以,我还是要显式处理null,过滤非空元素,比如:

data.stream()
    .filter(item -> item != null)
    .skip(1)
    .findFirst()
    .ifPresent(System.out::println);

是否有任何替代方法可以避免显式处理 null 作为:item != null

您可以使用 .filter(Objects::nonNull) 使用为此目的添加的方法 Objects.nonNull(…)

无法避免显式过滤,除非您首先避免在源列表中包含 null

请注意,如果 Optional 在这种情况下处理 null 会很奇怪,因为它会产生一个空的可选项,它具有“没有第一个元素”的语义,这意味着“流是空的”这是错误的。

显式处理 nulls 是这里最简洁的解决方案,因为它还允许您明确判断是否需要 .filter(Objects::nonNull).skip(1).skip(1).filter(Objects::nonNull)

…或.map(s->s==null? "null-replacement": s).findFirst()

这真的取决于你想做什么。如果您想将 null 视为有效值,答案与您想要跳过空值的答案不同。

如果您想在信息流中保留 "nulls":

    List<String> data = Arrays.asList("Foo", null, "Bar");
    data.stream().map(Optional::ofNullable).findFirst().flatMap(Function.identity()).ifPresent(System.out::println);  ;
    data.stream().map(Optional::ofNullable).skip(1).findFirst().flatMap(Function.identity()).ifPresent(System.out::println);

如果您想从流中删除空值,请使用 data.stream().filter(Objects::nonNull) 将其过滤掉(或者如您所述 o -> o != null,随您喜欢。