Optional <T> does not handle null elements
As I experimented, Optional<T>
does not handle items null
, so in the following example, it outputs NullPointerException
in the last statement:
List<String> data = Arrays.asList("Foo", null, "Bar");
data.stream().findFirst().ifPresent(System.out::println);
data.stream().skip(1).findFirst().ifPresent(System.out::println);
So, I still have to explicitly deal with null
and filter non-null items like:
data.stream()
.filter(item -> item != null)
.skip(1)
.findFirst()
.ifPresent(System.out::println);
Is there an alternative that avoids the explicit null handling like: item != null
source to share
It really depends on what you want to do. If you want to be treated null
as a valid value, the answer is different than if you want to skip zeros.
If you want to keep the zeros in your stream:
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);
If you want to remove zeros from your stream use data.stream().filter(Objects::nonNull)
to filter it (or, as you said, o -> o != null
whatever you choose.
source to share
You can use .filter(Objects::nonNull)
using the method Objects.nonNull(…)
added for this purpose.
There is no way to avoid explicit filtering unless you avoid being used null
in the original list.
Note that it would be weird to Optional
handle null
in this case, as it would give an empty optional, which had the semantics of "no first element", which implies "stream is empty" which is simply wrong.
Dealing with null
explicitly is the cleanest solution here, as it also allows you to explicitly specify if you want .filter(Objects::nonNull).skip(1)
, .skip(1).filter(Objects::nonNull)
...
... or .map(s->s==null? "null-replacement": s).findFirst()
source to share