Tim Peierls tim at
Tue Sep 25 05:27:53 PDT 2012

On Tue, Sep 25, 2012 at 7:37 AM, Doug Lea <dl at> wrote:

> As usual, my main concern is about impact on composition (aka modular
> reasoning). Any general-purpose higher-level utility using findAny without
> knowing if the source may include nulls will need to do something like:
>   boolean present;
>   T x;
>   try {
>        Optional<T> r = ...findAny(...);
>        if (present = r.isPresent()) x = r.get();
>   } catch(NPE ex) {
>       present = true;
>       x = null;
>   }

Or just:

Optional<T> r = ...filter(notNull()).findAny(...);

Not very nice.

The latter *is* pretty nice, reads very clearly, and if you apply filter
upstream, you won't have do it every time you findAny().

> I hate to be a pest about this, but the only choices I know that compose
> at all remain:
> 1. All stream ops throw NPE on any null element

Bleah: "Someone put a tack on teacher's chair, so the entire class has to
do extra homework."

> 2. All stream ops ignore nulls.

OK with me, but I'm betting not with Brian (because not size-preserving).

3. No use of Optionals; rely only on valueIfAbsent constructions

Bleah, opportunity for safer coding lost.

> And of these, choice (2) still seems most defensible.

What's wrong with prophylactic filtering if you think there might be nulls?

The "don't do anything special with nulls" approach that Brian is
advocating works quite well in practice in Guava. I've been using Guava
heavily, and I do not have to use anything like the contorted example that
Doug gave above. In a few cases I've had to use filter(notNull()) on a
FluentIterable (a "stream").

The analogue of Stream.into(...) in Guava is FluentIterable.toXXX(...),
where XXX is an immutable list or set (possibly sorted). Immutable
collections don't permit null elements, so you eventually get the NPE
downstream if you don't take care of it upstream. This is the best of both
worlds: You're free to deal with nulls in the stream as long as you get rid
of them by the time you .into(...) it.

There is an exception to the "don't do anything special with nulls" rule in
Guava, and as you might expect, it's for the analogue to findAny(),

*Warning:* avoid using a predicate that matches null. If null is matched in
this fluent iterable, a
be thrown.

That's not so hard, is it?


More information about the lambda-libs-spec-observers mailing list