Class Maybe<T,​E extends java.lang.Throwable>


  • public abstract class Maybe<T,​E extends java.lang.Throwable>
    extends java.lang.Object
    Class that wraps checked exceptions and tunnels them through stream operations or future graphs.

    The idea is to wrap checked exceptions inside Stream<Maybe<T, E>>, then map(), flatMap() and filter() away through normal stream operations. Exception is only thrown during terminal operations. For example, the following code fetches and runs pending jobs using a stream of Maybe:

    
       private Job fetchJob(long jobId) throws IOException;
    
       void runPendingJobs() throws IOException {
         Stream<Maybe<Job, IOException>> stream = activeJobIds.stream()
             .map(maybe(this::fetchJob))
             .filter(byValue(Job::isPending));
         Iterate.through(stream, m -> m.orElseThrow(IOException::new).runJob());
       }
     
    When it comes to futures, the following asynchronous code example handles exceptions type safely using Maybe.catchException():
    
       CompletionStage<User> assumeAnonymousIfNotAuthenticated(CompletionStage<User> stage) {
         CompletionStage<Maybe<User, AuthenticationException>> authenticated =
             Maybe.catchException(AuthenticationException.class, stage);
         return authenticated.thenApply(maybe -> maybe.orElse(e -> new AnonymousUser()));
       }
     
    • Method Summary

      Modifier and Type Method Description
      static <T,​E extends java.lang.Throwable>
      java.util.function.Predicate<Maybe<T,​E>>
      byValue​(java.util.function.Predicate<? super T> condition)
      Turns condition to a Predicate over Maybe.
      static <T,​E extends java.lang.Throwable>
      java.util.concurrent.CompletionStage<Maybe<T,​E>>
      catchException​(java.lang.Class<E> exceptionType, java.util.concurrent.CompletionStage<? extends T> stage)
      Returns a wrapper of stage that if stage failed with exception of exceptionType, that exception is caught and wrapped inside a Maybe to complete the wrapper stage normally.
      <X extends java.lang.Throwable>
      java.util.stream.Stream<T>
      catching​(CheckedConsumer<? super E,​? extends X> handler)
      Catches and handles exception with handler, and then skips it in the returned Stream.
      static <T,​E extends java.lang.Throwable>
      Maybe<T,​E>
      except​(E exception)
      Creates an exceptional Maybe for exception.
      abstract <T2> Maybe<T2,​E> flatMap​(java.util.function.Function<? super T,​Maybe<T2,​E>> function)
      Flat maps this using f unless it wraps exception.
      abstract Maybe<T,​E> ifPresent​(java.util.function.Consumer<? super T> consumer)
      Applies consumer if this is present.
      abstract boolean isPresent()
      Returns true unless this is exceptional.
      abstract <T2> Maybe<T2,​E> map​(java.util.function.Function<? super T,​? extends T2> function)
      Maps this using function unless it wraps exception.
      static <A,​B,​T,​E extends java.lang.Throwable>
      java.util.function.BiFunction<A,​B,​Maybe<T,​E>>
      maybe​(CheckedBiFunction<? super A,​? super B,​? extends T,​? extends E> function)
      Wraps function to be used for a stream of Maybe.
      static <A,​B,​T,​E extends java.lang.Throwable>
      java.util.function.BiFunction<A,​B,​Maybe<T,​E>>
      maybe​(CheckedBiFunction<? super A,​? super B,​? extends T,​? extends E> function, java.lang.Class<E> exceptionType)
      Wraps function to be used for a stream of Maybe.
      static <F,​T,​E extends java.lang.Throwable>
      java.util.function.Function<F,​Maybe<T,​E>>
      maybe​(CheckedFunction<? super F,​? extends T,​? extends E> function, java.lang.Class<E> exceptionType)
      Wraps function to be used for a stream of Maybe.
      static <F,​T,​E extends java.lang.Throwable>
      java.util.function.Function<F,​Maybe<T,​E>>
      maybe​(CheckedFunction<? super F,​? extends T,​E> function)
      Wraps function to be used for a stream of Maybe.
      static <T,​E extends java.lang.Throwable>
      Maybe<T,​E>
      maybe​(CheckedSupplier<? extends T,​? extends E> supplier)
      Invokes supplier and wraps the returned object or thrown exception in a Maybe<T, E>.
      static <T,​E extends java.lang.Throwable>
      Maybe<T,​E>
      maybe​(CheckedSupplier<? extends T,​? extends E> supplier, java.lang.Class<E> exceptionType)
      Wraps supplier to be used for a stream of Maybe.
      static <A,​B,​T,​E extends java.lang.Throwable>
      java.util.function.BiFunction<A,​B,​java.util.stream.Stream<Maybe<T,​E>>>
      maybeStream​(CheckedBiFunction<? super A,​? super B,​? extends java.util.stream.Stream<? extends T>,​? extends E> function)
      Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.
      static <A,​B,​T,​E extends java.lang.Throwable>
      java.util.function.BiFunction<A,​B,​java.util.stream.Stream<Maybe<T,​E>>>
      maybeStream​(CheckedBiFunction<? super A,​? super B,​? extends java.util.stream.Stream<? extends T>,​? extends E> function, java.lang.Class<E> exceptionType)
      Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.
      static <F,​T,​E extends java.lang.Throwable>
      java.util.function.Function<F,​java.util.stream.Stream<Maybe<T,​E>>>
      maybeStream​(CheckedFunction<? super F,​? extends java.util.stream.Stream<? extends T>,​? extends E> function, java.lang.Class<E> exceptionType)
      Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.
      static <F,​T,​E extends java.lang.Throwable>
      java.util.function.Function<F,​java.util.stream.Stream<Maybe<T,​E>>>
      maybeStream​(CheckedFunction<? super F,​? extends java.util.stream.Stream<? extends T>,​E> function)
      Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.
      static <T,​E extends java.lang.Throwable>
      java.util.stream.Stream<Maybe<T,​E>>
      maybeStream​(CheckedSupplier<? extends java.util.stream.Stream<? extends T>,​? extends E> supplier, java.lang.Class<E> exceptionType)
      Invokes supplier and wraps the returned Stream<T> or thrown exception into a stream of Maybe<T, E>.
      static <T,​E extends java.lang.Throwable>
      java.util.stream.Stream<Maybe<T,​E>>
      maybeStream​(CheckedSupplier<? extends java.util.stream.Stream<? extends T>,​E> supplier)
      Invokes supplier and wraps the returned Stream<T> or thrown exception into a stream of Maybe<T, E>.
      static <T,​E extends java.lang.Throwable>
      Maybe<T,​E>
      of​(T value)
      Creates a Maybe for value.
      abstract <X extends java.lang.Throwable>
      T
      orElse​(CheckedFunction<? super E,​? extends T,​X> function)
      Either returns the encapsulated value, or translates exception using function.
      T orElseThrow()
      Returns the encapsulated value or throws exception.
      T orElseThrow​(java.util.function.Function<? super E,​? extends E> exceptionWrapper)
      Either returns success value, or throws exception created by exceptionWrapper.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • of

        public static <T,​E extends java.lang.Throwable> Maybe<T,​E> of​(T value)
        Creates a Maybe for value.
        Parameters:
        value - can be null
      • except

        public static <T,​E extends java.lang.Throwable> Maybe<T,​E> except​(E exception)
        Creates an exceptional Maybe for exception.

        If exception is an InterruptedException, the current thread is re-interrupted as a standard practice to avoid swallowing the interruption signal.

      • map

        public abstract <T2> Maybe<T2,​E> map​(java.util.function.Function<? super T,​? extends T2> function)
        Maps this using function unless it wraps exception.
      • flatMap

        public abstract <T2> Maybe<T2,​E> flatMap​(java.util.function.Function<? super T,​Maybe<T2,​E>> function)
        Flat maps this using f unless it wraps exception.
      • isPresent

        public abstract boolean isPresent()
        Returns true unless this is exceptional.
      • ifPresent

        public abstract Maybe<T,​E> ifPresent​(java.util.function.Consumer<? super T> consumer)
        Applies consumer if this is present. Returns this.
      • orElse

        public abstract <X extends java.lang.Throwable> T orElse​(CheckedFunction<? super E,​? extends T,​X> function)
                                                          throws X extends java.lang.Throwable
        Either returns the encapsulated value, or translates exception using function.
        Throws:
        X extends java.lang.Throwable
      • orElseThrow

        public final T orElseThrow()
                            throws E extends java.lang.Throwable
        Returns the encapsulated value or throws exception.

        If this encapsulates an exception, a wrapper exception of type E is thrown to capture the caller's stack trace with the original exception as the cause.

        Consider to use orElseThrow(Function) to retain stack trace by wrapping exceptions, for example: orElseThrow(IOException::new).

        If InterruptedException is thrown, the current thread's Thread.interrupted() bit is cleared because it's what most code expects when they catch an InterruptedException.

        No exception wrapping is attempted for InterruptedException.

        Throws:
        E extends java.lang.Throwable
      • orElseThrow

        public final T orElseThrow​(java.util.function.Function<? super E,​? extends E> exceptionWrapper)
                            throws E extends java.lang.Throwable
        Either returns success value, or throws exception created by exceptionWrapper.

        It's recommended for exceptionWrapper to wrap the original exception as the cause.

        Throws:
        E extends java.lang.Throwable
      • catching

        public final <X extends java.lang.Throwable> java.util.stream.Stream<T> catching​(CheckedConsumer<? super E,​? extends X> handler)
                                                                                  throws X extends java.lang.Throwable
        Catches and handles exception with handler, and then skips it in the returned Stream. This is specially useful in a Stream chain to handle and then ignore exceptional results.
        Throws:
        X extends java.lang.Throwable
      • byValue

        public static <T,​E extends java.lang.Throwable> java.util.function.Predicate<Maybe<T,​E>> byValue​(java.util.function.Predicate<? super T> condition)
        Turns condition to a Predicate over Maybe. The returned predicate matches any Maybe with a matching value, as well as any exceptional Maybe so as not to accidentally swallow exceptions.
      • maybe

        public static <T,​E extends java.lang.Throwable> Maybe<T,​E> maybe​(CheckedSupplier<? extends T,​? extends E> supplier)
        Invokes supplier and wraps the returned object or thrown exception in a Maybe<T, E>.

        Unchecked exceptions will be immediately propagated without being wrapped.

      • maybeStream

        public static <T,​E extends java.lang.Throwable> java.util.stream.Stream<Maybe<T,​E>> maybeStream​(CheckedSupplier<? extends java.util.stream.Stream<? extends T>,​E> supplier)
        Invokes supplier and wraps the returned Stream<T> or thrown exception into a stream of Maybe<T, E>.

        Useful to be passed to Stream.flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>).

        Unchecked exceptions will be immediately propagated without being wrapped.

      • maybe

        public static <F,​T,​E extends java.lang.Throwable> java.util.function.Function<F,​Maybe<T,​E>> maybe​(CheckedFunction<? super F,​? extends T,​E> function)
        Wraps function to be used for a stream of Maybe.

        Unchecked exceptions will be immediately propagated without being wrapped.

      • maybeStream

        public static <F,​T,​E extends java.lang.Throwable> java.util.function.Function<F,​java.util.stream.Stream<Maybe<T,​E>>> maybeStream​(CheckedFunction<? super F,​? extends java.util.stream.Stream<? extends T>,​E> function)
        Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.

        Useful to be passed to Stream.flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>).

        Unchecked exceptions will be immediately propagated without being wrapped.

      • maybe

        public static <A,​B,​T,​E extends java.lang.Throwable> java.util.function.BiFunction<A,​B,​Maybe<T,​E>> maybe​(CheckedBiFunction<? super A,​? super B,​? extends T,​? extends E> function)
        Wraps function to be used for a stream of Maybe.

        Unchecked exceptions will be immediately propagated without being wrapped.

      • maybeStream

        public static <A,​B,​T,​E extends java.lang.Throwable> java.util.function.BiFunction<A,​B,​java.util.stream.Stream<Maybe<T,​E>>> maybeStream​(CheckedBiFunction<? super A,​? super B,​? extends java.util.stream.Stream<? extends T>,​? extends E> function)
        Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.

        Useful to be passed to Stream.flatMap(java.util.function.Function<? super T, ? extends java.util.stream.Stream<? extends R>>).

        Unchecked exceptions will be immediately propagated without being wrapped.

      • maybe

        public static <T,​E extends java.lang.Throwable> Maybe<T,​E> maybe​(CheckedSupplier<? extends T,​? extends E> supplier,
                                                                                     java.lang.Class<E> exceptionType)
        Wraps supplier to be used for a stream of Maybe.

        Normally one should use maybe(CheckedSupplier) unless E is an unchecked exception type.

        For GWT code, wrap the supplier manually, as in:

        
           private static <T> Maybe<T, FooException> foo(
               CheckedSupplier<T, FooException> supplier) {
             try {
               return Maybe.of(supplier.get());
             } catch (FooException e) {
               return Maybe.except(e);
             }
           }
         
      • maybeStream

        public static <T,​E extends java.lang.Throwable> java.util.stream.Stream<Maybe<T,​E>> maybeStream​(CheckedSupplier<? extends java.util.stream.Stream<? extends T>,​? extends E> supplier,
                                                                                                                    java.lang.Class<E> exceptionType)
        Invokes supplier and wraps the returned Stream<T> or thrown exception into a stream of Maybe<T, E>.
      • maybe

        public static <F,​T,​E extends java.lang.Throwable> java.util.function.Function<F,​Maybe<T,​E>> maybe​(CheckedFunction<? super F,​? extends T,​? extends E> function,
                                                                                                                                  java.lang.Class<E> exceptionType)
        Wraps function to be used for a stream of Maybe.

        Normally one should use maybe(CheckedFunction) unless E is an unchecked exception type.

        For GWT code, wrap the function manually, as in:

        
           private static <F, T> Function<F, Maybe<T, FooException>> foo(
               CheckedFunction<F, T, FooException> function) {
             return from -> {
               try {
                 return Maybe.of(function.apply(from));
               } catch (FooException e) {
                 return Maybe.except(e);
               }
             };
           }
         
      • maybeStream

        public static <F,​T,​E extends java.lang.Throwable> java.util.function.Function<F,​java.util.stream.Stream<Maybe<T,​E>>> maybeStream​(CheckedFunction<? super F,​? extends java.util.stream.Stream<? extends T>,​? extends E> function,
                                                                                                                                                                 java.lang.Class<E> exceptionType)
        Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.
      • maybe

        public static <A,​B,​T,​E extends java.lang.Throwable> java.util.function.BiFunction<A,​B,​Maybe<T,​E>> maybe​(CheckedBiFunction<? super A,​? super B,​? extends T,​? extends E> function,
                                                                                                                                                    java.lang.Class<E> exceptionType)
        Wraps function to be used for a stream of Maybe.

        Normally one should use maybe(CheckedBiFunction) unless E is an unchecked exception type.

        For GWT code, wrap the function manually, as in:

        
           private static <A, B, T> BiFunction<A, B, Maybe<T, FooException>> foo(
               CheckedBiFunction<A, B, T, FooException> function) {
             return (a, b) -> {
               try {
                 return Maybe.of(function.apply(a, b));
               } catch (FooException e) {
                 return Maybe.except(e);
               }
             };
           }
         
      • maybeStream

        public static <A,​B,​T,​E extends java.lang.Throwable> java.util.function.BiFunction<A,​B,​java.util.stream.Stream<Maybe<T,​E>>> maybeStream​(CheckedBiFunction<? super A,​? super B,​? extends java.util.stream.Stream<? extends T>,​? extends E> function,
                                                                                                                                                                                   java.lang.Class<E> exceptionType)
        Wraps function that returns Stream<T> to one that returns Stream<Maybe<T, E>> with exceptions of type E wrapped.
      • catchException

        public static <T,​E extends java.lang.Throwable> java.util.concurrent.CompletionStage<Maybe<T,​E>> catchException​(java.lang.Class<E> exceptionType,
                                                                                                                                    java.util.concurrent.CompletionStage<? extends T> stage)
        Returns a wrapper of stage that if stage failed with exception of exceptionType, that exception is caught and wrapped inside a Maybe to complete the wrapper stage normally.

        This is useful if the asynchronous code is interested in recovering from its own exception without having to deal with other exception types.