我在实验中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
答案 0 :(得分:8)
您可以使用为此目的添加的方法Objects.nonNull(…)
来使用.filter(Objects::nonNull)
。
除非您首先避免在源列表中使用null
,否则无法避免显式过滤。
请注意,如果Optional
在这种情况下处理null
会很奇怪,因为它会产生一个空的可选项,它具有“没有第一个元素”的语义,意味着“流”是空的“这是错的。
明确地处理null
是最干净的解决方案,因为它还允许您明确告诉您是否需要.filter(Objects::nonNull).skip(1)
,.skip(1).filter(Objects::nonNull)
......
...或.map(s->s==null? "null-replacement": s).findFirst()
答案 1 :(得分:3)
这实际上取决于你想做什么。如果您希望将null
视为有效值,则答案与您想要跳过空值的答案不同。
如果你想保持&#34; nulls&#34;在你的流中:
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
,无论您喜欢什么。