Try-Success-Failure API: Java implementation of the famous Scala counterpart
Source code: Try-Success-Failure API for Java
This API is a Java implementation of the Scala Try API, originally implemented by the guys at Twitter and later added to the Scala Standard Library.
The Try type represents a computation that may fail. If the computation succeeds, it returns
the value wrapped in a Try.Success; otherwise, it returns the
java.lang.Exception wrapped in a Try.Failure.
To use Try, you need to call the Try.apply(FailableSupplier) method passing in a lambda with
the same signature as a standard java.util.function.Supplier.
Indeed, FailableSupplier is just a java.util.function.Supplier with
throws Exception added to its get method.
For example, Try can be used to perform division on a user-defined input, without having to handle exceptions explicitly everywhere they might occur.
An important property of Try shown in the divide method of the MainExample class is its ability
to pipeline (chain if you prefer) operations, catching exceptions along the way thanks to its flatMap method.
If you are not a seasoned functional programming geek, concepts such as flatMap/map might not be easy to grasp
at first. However, you’ll get used to them and, in the end, you’ll love them. Moreover, you’re going to encounter
these methods more and more often since some important Java 8 classes already implement them
(e.g. java.util.Optional and java.util.stream.Stream). For now, just take for
granted that to pipeline more than two operations, say N, you just need to chain them by using N - 1
flatMap calls and a final call to map. E.g.: Suppose you have 3 variables (x, y and z)
of type Try and you just want to sum them up. The code you need for doing that is the
following:
x.flatMap(a -> y.flatMap(b -> z.map(c -> a + b + c)))
Apart from map and flatMap, Try has many other useful methods. See the TryTest
class for thorough coverage of all methods.
Usage example
System.out.println("Integer division");
System.out.println("Enter the dividend press Return and then enter the divisor: ");
Scanner dividend = new Scanner(System.in);
Scanner divisor = new Scanner(System.in);
Try<Integer> num = Try.apply(dividend::nextInt);
Try<Integer> denom = Try.apply(divisor::nextInt);
Try<Integer> result = num.flatMap(x -> denom.map(y -> x / y));
Try<String> resultTryStr = result.map(i -> "The result of division is: " + i);
String resultStr = resultTryStr.getOrElse("You must've divided by zero or entered something that's not an Int. Try again!");
System.out.println(resultStr);
In the example above, if you enter two valid integers and the second one—the divisor—is nonzero,
then the code prints out The result of division is: $RESULT, where $RESULT is the result of dividing the first
number by the second. On the other hand, if you enter invalid input—such as a string—or the second
number is zero, you’ll get the message You must've divided by zero or entered something that's not an Int. Try again!
printed out.
Anyway, as I already said, see the TryTest class for thorough coverage of all methods.
Final Notes
Any criticism or suggestions are more than welcome!
Source code: Try-Success-Failure API for Java