简体   繁体   中英

java streams: elegant way to filter according an exception is thrown

Is there any more elegant way to filter according if an exception is thrown?

I mean, currently my code looks like:

stream.filter(item -> {
    try {
        validator.with(reference)
            .hasAccess(this.authzManager)
            .isOwner();
        } catch (EspaiDocFault | DataAccessException e) {
            return false;
        }
        return true;
    }
)

What I'm trying to do is if an exception is thrown current item stream has to be filtered.

I'm looking for any existing util class or something similar...

The Vavr library has a Try class that can do what you want:

stream.filter(item -> Try.of(() -> validator.with(reference)
                .hasAccess(this.authzManager)
                .isOwner()).getOrElse(false))

Edit : if you actually want to know whether the exception was thrown or not, Vavr can do that too:

stream.filter(item -> Try.of([...]).isSuccess())

Alternatively, wrap the whole thing in a method:

stream.filter(this::getMyBooleanWithinMyTry)

A very common approach I've seen in many variations is to write own functional interface that will allow a checked exception to be thrown (1) and to adapt that solution to a built-in interface (2).

/**
 * An EPredicate is a Predicate that allows a checked exception to be thrown.
 *
 * @param <T> the type of the input to the predicate
 * @param <E> the allowed exception
 */
@FunctionalInterface
public interface EPredicate<T, E extends Exception> {

    /**
     * (1) the method permits a checked exception
     */
    boolean test(T t) throws E;

    /**
     * (2) the method adapts an EPredicate to a Predicate.
     */
    static <T, E extends Exception> Predicate<T> unwrap(EPredicate<T, E> predicate) {
        return t -> {
            try {
                return predicate.test(t);
            } catch (Exception e) {
                return false;
            }
        };
    }

}

An example looks quite elegant:

.stream()
.filter(EPredicate.<ItemType, Exception>unwrap(item -> validator.[...].isOwner()))

where,

  • ItemType is the type of item ;
  • Exception is a common parent of EspaiDocFault and DataAccessException .

.stream()
.filter(EPredicate.unwrap(item -> validator.[...].isOwner()))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM