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");
}