Потоки java: элегантный способ фильтрации по исключению

Есть ли более элегантный способ фильтрации в случае возникновения исключения?

Я имею в виду, что в настоящее время мой код выглядит так:

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

То, что я пытаюсь сделать, - это если возникает исключение, текущий поток элементов должен быть отфильтрован.

Я ищу любой существующий класс утилиты или что-то подобное ...

Было бы более элегантно, если бы вы вызывали разные методы, которые возвращают false (или пустой Optional, который вы можете связать со следующим вызовом с map) вместо того, чтобы генерировать эти исключения.

Eran 13.12.2018 15:59

@FedericoPeraltaSchaffner Нет, я не могу изменить эти методы

Jordi 13.12.2018 16:15

А как насчет того, что элемент потока (item) не используется внутри предиката filter?

fps 13.12.2018 16:28

@FedericoPeraltaSchaffner, и возвращаемое значение isOwner полностью игнорируется ....

Ousmane D. 13.12.2018 17:42

@Aomine Да, но я думаю (с небольшим количеством воображения) это могло быть сделано намеренно, то есть если OP просто хотел отсутствие или наличие исключения в качестве побочного эффекта, чтобы проверить, все ли в порядке ... Кто знает? В любом случае, похоже, плохой дизайн ...

fps 13.12.2018 17:53

@FedericoPeraltaSchaffner Теперь, когда вы упомянули, это имеет больше смысла, но все же ответ на ваш предыдущий вопрос должен быть интересным.

Ousmane D. 13.12.2018 18:00
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
6
120
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

В библиотеке Вавр есть класс 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).

/**
 * 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()))

где,

  • ItemType - это тип item;
  • Exception является общим родителем EspaiDocFault и DataAccessException.

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

Другие вопросы по теме