Loose ends: Optional

Brian Goetz brian.goetz at oracle.com
Fri May 24 12:20:23 PDT 2013


Proposed spec for methods on Optional, which would have the obvious 
counterparts in Optional{Int,Long,Double}.

These methods are known to be useful and seem mostly harmless now that 
other things have settled.  (I don't think they greatly increase the 
moral hazard of Optional in general, and they do make it more expressive.)


     /**
      * If a value is present, and the value matches the given predicate,
      * return an {@code Optional} describing the value, otherwise return an
      * empty {@code Optional}.
      *
      * @param predicate a predicate to apply to the value, if present
      * @throws NullPointerException if the predicate is null
      * @return an {@code Optional} describing the value of this {@code 
Optional}
      * if a value is present and the value matches the given predicate,
      * otherwise an empty {@code Optional}
      */
     public Optional<T> filter(Predicate<T> predicate) {
         Objects.requireNonNull(predicate);
         if (!isPresent())
             return this;
         else
             return predicate.test(value) ? this : empty();
     }

     /**
      * If a value is present, apply the provided mapping function to it,
      * and if the result is non-null, return an {@code Optional} 
describing the
      * result.  Otherwise return an empty {@code Optional}.
      *
      * @param <U> The type of the result of the mapping function
      * @param mapper a mapping function to apply to the value, if present
      * @throws NullPointerException if the mapping function is null
      * @return an {@code Optional} describing the result of applying a 
mapping
      * function to the value of this {@code Optional}, if a value is 
present,
      * otherwise an empty {@code Optional}
      */
     public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
         Objects.requireNonNull(mapper);
         if (!isPresent())
             return empty();
         else {
             U result = mapper.apply(value);
             return result == null ? empty() : Optional.of(result);
         }
     }

     /**
      * If a value is present, apply the provided {@code Optional}-bearing
      * mapping function to it, return that result, otherwise return an 
empty
      * {@code Optional}.
      *
      * @param <U> The type parameter to the {@code Optional} returned by
      * @param mapper a mapping function to apply to the value, if present
      *           the mapping function
      * @throws NullPointerException if the mapping function is null or 
returns
      * a null result
      * @return the result of applying an {@code Optional}-bearing mapping
      * function to the value of this {@code Optional}, if a value is 
present,
      * otherwise an empty {@code Optional}
      */
     public<U> Optional<U> flatMap(Function<? super T, ? extends 
Optional<U>> mapper) {
         Objects.requireNonNull(mapper);
         if (!isPresent())
             return empty();
         else {
             return Objects.requireNonNull(mapper.apply(value));
         }
     }
     }


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