Несколько фильтров, примененных к одному списку в Java 8+ - PullRequest
0 голосов
/ 04 октября 2019

Как можно достичь, чтобы передать «список фильтров» в поток в Java 8, вместо того, чтобы применять их по отдельности, как показано в следующем примере?

https://howtodoinjava.com/java8/stream-multiple-filters-example/

Цель состоит в том, чтобы динамически создать список фильтров, один из способов - перебрать список фильтров и применить его к фильтруемому списку.

Любая другая идея?

ОБНОВЛЕНИЕ:

Спасибо за комментарий предиката:

   final Predicate<?> predicate = new Predicate<?>() {

        @Override 
        public boolean test(Object object) {
            return false; //TODO: Implement first predicate
        }
    } ;

    predicate.and(...); //Implement another predicate.

С уважением

~ M

Ответы [ 3 ]

4 голосов
/ 04 октября 2019

Предикаты можно связать с помощью оператора and или or. Вы хотите, чтобы ваш объединенный предикат был предикатом, который соответствует объектам, которые соответствуют всем предикатам компонента, или хотя бы одному из них? Если вы хотите смоделировать цепочку вызовов filter:

someStream.filter(...)
            .filter(...)
            .filter(...)
            .filter(...)

Тогда вам следует использовать and.

В зависимости от того, что вы выберете, вы можете использовать любой из этих методов:

public static <T> Predicate<T> combineFilters(List<Predicate<T>> filters) {
    return filters.stream().reduce(Predicate::and).orElse(x -> true);
}

public static <T> Predicate<T> combineFilters(List<Predicate<T>> filters) {
    return filters.stream().reduce(Predicate::or).orElse(x -> true);
}

Использование:

someStream.filter(combineFilters(aListOfFilters))
    ...
0 голосов
/ 09 октября 2019
   List<Integer> numbers = Arrays.asList(1,2,null,3,0,0,8);

   Predicate<Integer> fitlerPredicate = i -> i != null && i > 0;
    List<Integer> collect = numbers.stream().filter(fitlerPredicate).collect(Collectors.toList());
    collect.forEach(System.out::println);

Вы можете объединить список критериев фильтра с помощью оператора && и передать это значение в операцию фильтрации потока api

0 голосов
/ 04 октября 2019

Если у вас есть генератор предикатов, такой как этот тестовый

    Supplier<Integer> seed = () -> (int) (Math.random() * 9 + 2); // in [2, 11]
    Supplier<Predicate<Integer>> generator = () -> {
        int seedNow = seed.get();
        return (Integer value) -> (value % seedNow == 0);
    };

, который, как вы знаете, предоставляет конечную последовательность фильтров,

вам лучше накопить их до того, какактуальная фильтрация

    Predicate<Integer> cumulative = Stream.generate(generator)
            .limit(5)
            .reduce(Predicate::and).orElse((value) -> true);

и затем эксплойт

    List<Integer> output = IntStream.range(0, 300)
            .boxed()
            .filter(cumulative)
            .collect(Collectors.toList());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...