Stream proposal and null results
Scott Carey
scottcarey at apache.org
Fri May 11 10:06:06 PDT 2012
In the stream API draft proposal, I noticed that null was used to signify
a failed computation or filter:
Method matching =
Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
.filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
.filter(m -> Arrays.equals(m.getParameterTypes(),
parameterClasses))
.filter(m -> Objects.equals(m.getReturnType(), returnType))
.getFirst();
if (matching == null)
throw new InternalError("Enclosing method not found");
return matching;
It would be very useful to avoid requiring clients to check the result for
null. This error prone null check pattern can be avoided and pushed into
the framework with something like:
return
Arrays.asList(enclosingInfo.getEnclosingClass().getDeclaredMethods())
.filter(m -> Objects.equals(m.getName(), enclosingInfo.getName())
.filter(m -> Arrays.equals(m.getParameterTypes(),
parameterClasses))
.filter(m -> Objects.equals(m.getReturnType(), returnType))
.getFirstOrElse(() -> throw new InternalError("Enclosing method
not found"));
A couple other signatures for the last line are very useful as well:
.getFirstOrElse(() -> someDefaultComputation()));
.getFirstOrElse(someDefaultValue));
If the only API contract for a computation with no result is to return
null, then the pattern
T tempVar = values.someComputations().getResult();
if (null == tempVar) {
// do something about no result here
}
return tempVar;
will be extremely common boilerplate that can be avoided .
I think there are a three signatures that together remove the boilerplate.
Below I have changed the name from getFirstOrElse to getFirst:
void getFirst(Runnable elseAction)
T getFirst(Callable<T> elseResult)
T getFirst(T elseVal)
T getFirst() is then simply a shortcut for
T getFirst((T)null);
There is likely something more elegant than multiplying the number of
method signatures for every method that has an optional result.
More information about the lambda-dev
mailing list