Nulls

Remi Forax forax at univ-mlv.fr
Tue Sep 25 05:55:31 PDT 2012


On 09/25/2012 02:27 PM, Tim Peierls wrote:
> On Tue, Sep 25, 2012 at 7:37 AM, Doug Lea <dl at cs.oswego.edu 
> <mailto:dl at cs.oswego.edu>> 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).

and as Joe said, it doesn't preserve the index too.

>
>     3. No use of Optionals; rely only on valueIfAbsent constructions
>
>
> Bleah, opportunity for safer coding lost.

or it requires to dudplicate calls that returns an Optional, 
findAny/findAnyOrNull.

>
>     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(), FluentIterable.firstMatch(Predicate):
>
> *Warning:* avoid using a |predicate| that matches |null|. If |null| is 
> matched in this fluent iterable, a |NullPointerException| 
> <http://download.oracle.com/javase/6/docs/api/java/lang/NullPointerException.html?is-external=true> will 
> be thrown.
>
> That's not so hard, is it?
>
> --tim

Rémi



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