An instance of Try<> can store either the:
- result
- exception
When to Use
Use Try<> whenever you want to collect the errors occurring for an element instead of terminating the Stream
Example Code
Problem
We want to parse all the valid dates and return them IF at least half of them are parseable, otherwise, we should throw an exception. This time we can’t let an exception terminate the execution of our stream. Instead, we want to go through all of the items and collect both parsed dates and exceptions. For example, if we are given 3 correctly-formatted dates and 2 invalid ones, we should return the 3 ones that we were able to parse correctly
Solution
List<Try<Date>> tries = dateList.stream()
.map(s -> Try.of(
() -> format.parse(s) // throwing code
))
.collect(toList());
If the throwing code crashes with an exception, the surrounding Try.of function will catch that exception and return a failed Try. Therefore, in the tries list above, there can be items with isSuccess() either true or false.
To count the success ratio:
double successRatio = tries.stream()
.mapToInt(t -> t.isSuccess() ? 1 : 0)
.average()
.orElse(0);
Then,
if (successRatio > .5) {
return tries.stream()
.filter(Try::isSuccess)
.map(Try::get)
.collect(toList());
} else {
throw new IllegalArgumentException("Too many invalid dates");
}