Java Streams:抛出异常的优雅方法

时间:2018-12-13 14:56:51

标签: java exception java-8 exception-handling java-stream

是否有引发异常的更优雅的过滤方法?

我的意思是,当前我的代码如下:

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

我想做的是如果引发异常,则必须过滤当前项目流。

我正在寻找任何现有的util类或类似的东西...

2 个答案:

答案 0 :(得分:2)

Vavr库具有一个Try类,可以执行您想要的操作:

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

编辑:如果您实际上想知道是否引发了异常,Vavr也可以这样做:

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

或者,将整个内容包装在一个方法中:

stream.filter(this::getMyBooleanWithinMyTry)

答案 1 :(得分:2)

我在许多变体中看到的一种非常常见的方法是编写自己的功能接口,该功能接口将允许抛出已检查的异常(1)并使该解决方案适应内置接口(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;
            }
        };
    }

}

一个例子看起来很优雅:

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

其中

  • ItemTypeitem的类型;
  • ExceptionEspaiDocFaultDataAccessException的共同父母。

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