All Downloads are FREE. Search and download functionalities are using the official Maven repository.

javascalautils.Try Maven / Gradle / Ivy

There is a newer version: 1.11.2
Show newest version
/**
 * Copyright 2015 Peter Nerg
 *
 * 

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of the License at * *

http://www.apache.org/licenses/LICENSE-2.0 * *

Unless required by applicable law or agreed to in writing, software distributed under the * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing permissions and * limitations under the License. */ package javascalautils; import java.util.Iterator; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Stream; /** * The Try type represents a computation that may either result in an exception, or return a * successfully computed value.
* Typical use case is situations where parallel computation takes place resulting in more than one * response where it's possible that one or more computations fail.
* Though it might not be desirable to raise an exception for failed computations hence the Try acts * a place holder for a response that is either failed or successful.
* Instances of Try, are either an instance of {@link Success} or {@link Failure}.
* Example of usage:
* *

* *
 * Try<SomeData> getSomeData(SomeInput input) {
 *     try {
 *         // readUserFromDB throws if no user exists
 *         SomeData data = readUserFromDB(input);
 *         return new Success<>(data);
 *     } catch (SomeException ex) {
 *         return new Failure<>(ex);
 *     }
 * }
 * 
* *
* * A more elaborate way is to provide a {@link ThrowableFunction0 checked function} provided to the * {@link #apply(ThrowableFunction0)} method.
* *
* *
 * Try<Integer> resultSuccess = Try.apply(() -> 9 / 3); // results in Success(3)
 * Try<Integer> resultFailure = Try.apply(() -> 9 / 0); // results in Failure(ArithmeticException)
 * 
* *
* * Or let us re-write the first example to use the {@link #apply(ThrowableFunction0)} method.
* *
* *
 * Try<SomeData> getSomeData(SomeInput input) {
 *     // readUserFromDB throws if no user exists
 *     Try.apply(() -> readUserFromDB(input));
 * }
 * 
* *
* * To make it even more concise we can create Try instances just by using {@link * TryCompanion#Try(ThrowableFunction0) Try(ThrowableFunction0)}.
* This however requires you to statically import the proper methods from the {@link TryCompanion * companion class} related to Try. * *
* *
 * import static javascalautils.TryCompanion.Try;
 *
 * Try<SomeData> getSomeData(SomeInput input) {
 *     // readUserFromDB throws if no user exists
 *     Try(() -> readUserFromDB(input));
 * }
 * 
* *
* * @author Peter Nerg * @since 1.0 * @param The type of the value represented by this Try */ public interface Try extends Iterable { /** * Creates an instance of Try.
* If a null or non-throwable value is provided then {@link Success} is returned * containing the value, else {@link Failure} containing the provided throwable. * * @param The type for the Try * @param value The value for this to create a Try * @return The Try instance * @since 1.0 */ static Try apply(T value) { return value instanceof Throwable ? new Failure<>((Throwable) value) : new Success<>(value); } /** * Creates an instance of Try wrapping the result of the provided function.
* If the function results in a value then {@link Success} with the value is returned.
* In case the function raises an exception then {@link Failure} is returned containing that * exception.
* If null is provided as argument then the {@link #apply(Object)} is invoked.
* Example simple division by zero results in an exception. * *
* *
   * Try<Integer> resultSuccess = Try.apply(() -> 9 / 3); // results in Success(3)
   * Try<Integer> resultFailure = Try.apply(() -> 9 / 0); // results in Failure(ArithmeticException)
   * 
* *
* * @param The type for the Try * @param function The function to render either the value T or raise an exception. * @return The resulting Try instance wrapping what the function resulted in * @since 1.3 */ static Try apply(ThrowableFunction0 function) { if (function == null) { return apply((T) null); } try { return new Success<>(function.apply()); } catch (Throwable ex) { return new Failure<>(ex); } } /** * Returns true if the Try is a {@link Failure}, false otherwise. * * @return If the Try is a {@link Failure} * @since 1.0 */ default boolean isFailure() { return !isSuccess(); } /** * Returns true if the Try is a {@link Success}, false otherwise. * * @return If the Try is a {@link Success} * @since 1.0 */ boolean isSuccess(); /** * Returns the value from this {@link Success} or the value provided by the supplier if this is a * {@link Failure}. * * @param supplier The supplier to return the value in case of a {@link Failure} * @return The value from the Try or the supplier * @since 1.0 */ T getOrElse(Supplier supplier); /** * Returns the value if it is a {@link Success}, else null. * * @return The value of the Try or null. * @since 1.0 */ default T orNull() { return getOrElse(() -> null); } /** * Returns this Try if it's a {@link Success} or the value provided by the supplier if this * is a {@link Failure}. * * @param supplier The supplier to return the value in case of a {@link Failure} * @return This try or the value from the supplier */ Try orElse(Supplier> supplier); /** * Returns the value from this {@link Success} or throws the exception if this is a {@link * Failure}. * * @return The value of the {@link Success} * @throws Throwable The Throwable in case of a {@link Failure} * @since 1.0 */ T get() throws Throwable; /** * Completes this Try with an exception wrapped in a {@link Success}.
* The exception is either the exception that the Try failed with (if a {@link Failure}) or * an 'UnsupportedOperationException'. * * @return The value of the {@link Failure} in a {@link Success} * @since 1.0 */ Try failed(); /** * Applies the predicate to the value of the {@link Try} and either returns the Try if the * predicate matched or a {@link Failure}.
* One of the three outcomes are applicable: * *
    *
  • Instance is {@link Success} and predicate matches -> return this *
  • Instance is {@link Success} and predicate does not match -> return {@link Failure} *
  • Instance is {@link Failure} -> return this *
  • *
* * @param filter The filter to apply * @return The try matching the filter, either this if matching or a {@link Failure} in * case no match * @since 1.4 */ Try filter(Predicate filter); /** * Returns the Try's value in an {@link Iterator} if it is a {@link Success}, or an empty {@link * Iterator} if it is Failure.
* * @return The iterator for the Try * @since 1.0 */ Iterator iterator(); /** * Maps the given function to the value from this {@link Success} or returns this if this * is a {@link Failure}.
* This allows for mapping a {@link Try} containing some type to some completely different type. *
* The example converts a {@link Try} of type String to Integer. * *
* *
   * Try<String> t = ...
   * Try<Integer> t2 = t.map(v -> v.length);
   * 
* *
* * @param The type for the return value from the function * @param function The function to use * @return The Option containing the mapped value * @since 1.0 */ Try map(ThrowableFunction1 function); /** * Maps the given function to the value from this {@link Success} or returns this if this * is a {@link Failure}. * * @param The type for the return value from the function * @param function The function to use * @return The Option containing the mapped value * @since 1.2 */ Try flatMap(ThrowableFunction1> function); /** * Creates a new {@link Try} that in case this {@link Try} is a {@link Failure} will apply * the function to recover to a {@link Success}.
* Should this be a {@link Success} then this is returned, i.e. no new instance is * created.
* This is a kind of {@link #map(ThrowableFunction1)} for failures only.
* E.g.
* In case of t being successful then that value is passed on to recovered, in case * of failure then the recover function kicks in and returns the message from the throwable. * *
* *
   * Try<String> t = ...
   * Try<String> recovered = t.recover(t -> t.getMessage());
   *
   * 
* *
* * This statement will be Success(3) * *
* * Try<Integer> t = Try(() -> 9/3).recover(t -> 0) * *
* *
* Whilst this statement will be Success(0) as it is division-by-zero * *
* * Try<Integer> t = Try(() -> 9/0).recover(t -> 0) * *
* * @param function The function to apply in case of a {@link Failure} * @return The recovered Try * @since 1.4 */ Try recover(ThrowableFunction1 function); /** * Creates a new {@link Try} that in case this {@link Try} is a {@link Failure} will apply * the function to recover the {@link Try} rendered by the function.
* Should this be a {@link Success} the value is propagated as-is.
* This is a kind of {@link #map(ThrowableFunction1)} for failures only.
* E.g. * *
* *
   * Try<String> t = ...
   * Try<String> recovered = t.recover(t -> new Success<>(t.getMessage()));
   * 
* *
* * In case of t being successful then that value is passed on to recovered, in case * of failure then the recover function kicks in and returns the a {@link Success} with message * from the throwable. * * @param function The function to apply in case of a {@link Failure} * @return The recovered Try * @since 1.4 */ Try recoverWith(ThrowableFunction1> function); /** * Returns the Try's value in a Stream if it is a {@link Success}, or an empty Stream if it is a * {@link Failure}. * * @return The stream for the Try * @since 1.0 */ Stream stream(); /** * Returns this {@link Try} as an {@link Option}.
* If it is a {@link Success} then the value is wrapped in {@link Some} else {@link None} is * returned.
* Should the {@link Success} contain a null value the result will be {@link None} as * null values are per definition none/nothing. * * @return The {@link Option} representing this Try * @since 1.0 */ default Option asOption() { return Option.apply(orNull()); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy