Class Optionals

java.lang.Object
com.google.mu.util.Optionals

public final class Optionals extends Object
Utilities pertaining to Optional.
Since:
1.14
  • Method Details

    • optionally

      public static <T, E extends Throwable> Optional<T> optionally(boolean condition, CheckedSupplier<? extends T,E> supplier) throws E
      Returns an Optional that wraps the nullable result from supplier if condition is true, or else empty().

      Example: Optional<Double> avg = optionally(count > 0, () -> sum / count);

      Throws:
      NullPointerException - if supplier is null
      E
      Since:
      3.7
    • optional

      public static <T> Optional<T> optional(boolean condition, T value)
      Returns an Optional that wraps value if condition is true and value is not null, or else empty().

      Example: Optional<Foo> foo = optional(input.hasFoo(), input.getFoo());

      Since:
      3.7
    • asSet

      public static <T> Set<T> asSet(Optional<? extends T> optional)
      Returns an immutable singleton Set whose only element is the contained instance if it is present; an empty immutable Set otherwise.

      This is useful when you are trying to apply some side-effects on the value contained in the Optional:

      
       for (Foo foo : asSet(optionalFoo)) {
         // ...
       }
       
      While you could use optional.ifPresent(v -> ...), the lambda has limitations (no checked exceptions etc.). The body of the lambda can also become unwieldy if there are more than 5 lines of code, with conditionals and what not.

      If you need to add the Optional's contained value into another collection, consider results.addAll(asSet(optional)). The addAll() side effect stands out more crisply than in optional.ifPresent(results::add) where the important data flow into the results collection is somewhat buried and easy to miss.

      Lastly, if you need to check whether the optional contains a particular value, consider using asSet(optional).contains(value).

      Since:
      6.1
    • nonEmpty

      public static <C extends Collection<?>> Optional<C> nonEmpty(C collection)
      Returns Optional.empty() if collection is empty; otherwise wraps it with Optional.of(T).
      Since:
      8.3
    • both

      public static <A, B> BiOptional<A,B> both(Optional<? extends A> a, Optional<? extends B> b)
      If a and b are present, returns a BiOptional instance containing them; otherwise returns an empty BiOptional.
      Throws:
      NullPointerException - if a or b is null
      Since:
      5.7
    • inOrder

      public static <A, B> BiOptional<A,B> inOrder(Optional<? extends A> step1, Supplier<? extends Optional<? extends B>> step2)
      Similar to both(java.util.Optional<? extends A>, java.util.Optional<? extends B>), but only evaluates step2 if step1 is present.

      Useful if step2 is expensive or has side effects. For example, instead of:

      
       return parseUserId(userIdString)
           .flatMap(userId ->
               extractActiveWorklog()
                   .flatMap(worklog -> processUserWorklog(userId, worklog)));
       
      Do:
      
       return inOrder(parseUserId(userIdString), this::extractActiveWorklog)
           .flatMap((userId, worklog) -> processUserWorklog(userId, worklog));
       
      Throws:
      NullPointerException - if step1 or step2 is null
      Since:
      8.1
    • inOrder

      public static <A, B> BiOptional<A,B> inOrder(Optional<? extends A> step1, Function<? super A,? extends Optional<? extends B>> step2)
      Similar to both(java.util.Optional<? extends A>, java.util.Optional<? extends B>), but only evaluates step2 if step1 is present.

      Useful if step2 is expensive or has side effects. For example, instead of:

      
       return parseUserId(userIdString)
           .flatMap(userId ->
               extractActiveWorklog(userId)
                   .flatMap(worklog -> processUserWorklog(userId, worklog)));
       
      Do:
      
       return inOrder(parseUserId(userIdString), this::extractActiveWorklog)
           .flatMap((userId, worklog) -> processUserWorklog(userId, worklog));
       
      Throws:
      NullPointerException - if step1 or step2 is null
      Since:
      8.1
    • ifPresent

      public static <E extends Throwable> Premise ifPresent(OptionalInt optional, CheckedIntConsumer<E> consumer) throws E
      Invokes consumer if optional is present. Returns a Premise object to allow orElse() and friends to be chained. For example:
      
         ifPresent(findId(), System.out::print)
             .or(() -> ifPresent(findName(), System.out::print))
             .or(() -> ifPresent(findCreditCardNumber(), System.out::print))
             .orElse(() -> System.out.print("no identity found"));
       

      This method is very similar to JDK OptionalInt.ifPresent(java.util.function.IntConsumer) with a few differences:

      1. orElse() is chained fluently, compared to OptionalInt.ifPresentOrElse(java.util.function.IntConsumer, java.lang.Runnable).
      2. or() allows chaining arbitrary number of alternative options on arbitrary optional types.
      3. Propagates checked exceptions from the consumer.
      4. Syntax is consistent across one-Optional and two-Optional ifPresent() overloads.
      5. ifPresent(findId(), System.out::print) begins the statement with "if", which may read somewhat closer to regular if statements.
      Throws:
      E
    • ifPresent

      public static <E extends Throwable> Premise ifPresent(OptionalLong optional, CheckedLongConsumer<E> consumer) throws E
      Invokes consumer if optional is present. Returns a Premise object to allow orElse() and friends to be chained. For example:
      
         ifPresent(findId(), System.out::print)
             .or(() -> ifPresent(findName(), System.out::print))
             .or(() -> ifPresent(findCreditCardNumber(), System.out::print))
             .orElse(() -> System.out.print("id not found"));
       

      This method is very similar to JDK OptionalLong.ifPresent(java.util.function.LongConsumer) with a few differences:

      1. orElse() is chained fluently, compared to OptionalLong.ifPresentOrElse(java.util.function.LongConsumer, java.lang.Runnable).
      2. or() allows chaining arbitrary number of alternative options on arbitrary optional types.
      3. Propagates checked exceptions from the consumer.
      4. Syntax is consistent across one-Optional and two-Optional ifPresent() overloads.
      5. ifPresent(findId(), System.out::print) begins the statement with "if", which may read somewhat closer to regular if statements.
      Throws:
      E
    • ifPresent

      public static <E extends Throwable> Premise ifPresent(OptionalDouble optional, CheckedDoubleConsumer<E> consumer) throws E
      Invokes consumer if optional is present. Returns a Premise object to allow orElse() and friends to be chained. For example:
      
         ifPresent(findMileage(), System.out::print)
             .or(() -> ifPresent(findName(), System.out::print))
             .or(() -> ifPresent(findCreditCardNumber(), System.out::print))
             .orElse(() -> System.out.print("id mileage found"));
       

      This method is very similar to JDK OptionalDouble.ifPresent(java.util.function.DoubleConsumer) with a few differences:

      1. orElse() is chained fluently, compared to OptionalDouble.ifPresentOrElse(java.util.function.DoubleConsumer, java.lang.Runnable).
      2. or() allows chaining arbitrary number of alternative options on arbitrary optional types.
      3. Propagates checked exceptions from the consumer.
      4. Syntax is consistent across one-Optional and two-Optional ifPresent() overloads.
      5. ifPresent(findMileage(), System.out::print) begins the statement with "if", which may read somewhat closer to regular if statements.
      Throws:
      E
    • ifPresent

      public static <T, E extends Throwable> Premise ifPresent(Optional<T> optional, CheckedConsumer<? super T,E> consumer) throws E
      Invokes consumer if optional is present. Returns a Premise object to allow orElse() and friends to be chained. For example:
      
         ifPresent(findStory(), Story::tell)
             .or(() -> ifPresent(findGame(), Game::play))
             .or(() -> ifPresent(findMovie(), Movie::watch))
             .orElse(() -> print("Nothing to do"));
       

      This method is very similar to JDK Optional.ifPresent(java.util.function.Consumer<? super T>) with a few differences:

      1. orElse() is chained fluently, compared to Optional.ifPresentOrElse(java.util.function.Consumer<? super T>, java.lang.Runnable).
      2. or() allows chaining arbitrary number of alternative options on arbitrary optional types.
      3. Propagates checked exceptions from the consumer.
      4. Syntax is consistent across one-Optional and two-Optional ifPresent() overloads.
      5. ifPresent(findStory(), Story::tell) begins the statement with "if", which may read somewhat closer to regular if statements.
      Throws:
      E
    • ifPresent

      public static <A, B, E extends Throwable> Premise ifPresent(Optional<A> left, Optional<B> right, CheckedBiConsumer<? super A,? super B,E> consumer) throws E
      Invokes consumer if both left and right are present. Returns a Premise object to allow orElse() and friends to be chained. For example:
      
         ifPresent(when, where, Story::tell)
             .orElse(() -> print("no story"));
       
      Throws:
      E
    • ifPresent

      public static <A, B, E extends Throwable> Premise ifPresent(BiOptional<A,B> optional, CheckedBiConsumer<? super A,? super B,E> consumer) throws E
      Runs action if the pair is present. Allows chaining multiple BiOptional and Optional together. For example:
      
       ifPresent(both(firstName, lastName), (f, l) -> System.out.println(...))
           .or(() -> ifPresent(firstName, f -> ...))
           .or(() -> ifPresent(lastName, l -> ...))
           .orElse(...);
       
      Throws:
      E
      Since:
      5.0