1

I have a few predicates that I want to put in a list so I can then call stream().noneMatch() on my list. I successfully did this by creating named Predicates but how can I create them within an Arrays.asList()'s argument list?

Here's the working code that I'd like to convert:

ArrayList<Predicate<MyClass>> checks = new ArrayList<>();
Predicate<MyClass> isCond1 = myClassHelper::isCond1;
Predicate<MyClass> isCond2 = myClassHelper::isCond2;
checks.add(isCond1);
checks.add(isCond2);

I'd expect the result of the conversion to look something like this:

List<Predicate> checks = Arrays.asList(myClassHelper::isCond1, myClassHelper::isCond2);

or

List<Predicate> checks = Arrays.asList(a -> myClassHelper::isCond1, a -> myClassHelper::isCond2);

(neither of these are correct)
Where can I specify the argument for the conditions here?

Sorry if this could have been titled better, I always struggle with that.

  • What about `List> checks = Arrays.asList(a -> myClassHelper.isCond1(a), a -> myClassHelper.isCond2(a));` ? – lealceldeiro Mar 02 '22 at 12:54
  • @lealceldeiro This appears to work when I explicitly cast `a` to `MyClass`. Would there perhaps be a way to do this while still using the method reference operator(::)? – i_have_no_clue_man Mar 02 '22 at 13:01

2 Answers2

0

The first statement should work but you forgot to specify the predicate type Predicate<MyClass>, otherwise the compiler cannot infer it from the method references:

List<Predicate<MyClass>> checks2 = Arrays.asList(myClassHelper::isCond1, myClassHelper::isCond2);

Or using lambdas:

List<Predicate<MyClass>> checks3 = Arrays.asList(a -> myClassHelper.isCond1(a), a -> myClassHelper.isCond2(a));
M A
  • 71,713
  • 13
  • 134
  • 174
0

If you want to convert multiple Predicate to

List

List.of since JKD 9 is a better API(e.g the return list is immutable, rejecting null), check What is the difference between List.of and Arrays.asList? for details.

Stream

Stream.of is even better if you actually want to use Stream API.

Predicate

If there are multiple MyClass to test, combining the Predicate to one give your more flexibility, and looks more natural.

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;

public class MultiplePredicate {
    public static void main(String[] args) {
        List<MyClass> items = new ArrayList<>();
        items.add(new MyClass(1));
        items.add(new MyClass(2));
        items.add(new MyClass(3));
        //                                          drawback as compiler not smart enough
        Predicate<MyClass> allCondNotMatch = Stream.<Predicate<MyClass>>of(MyClassHelper::isCond1, MyClassHelper::isCond2)
                .map(Predicate::not)
                .reduce((myClass) -> true, Predicate::and);
        List<MyClass> itemsWithAllCondNotMatch = items.stream().filter(allCondNotMatch).toList();
        System.out.println(itemsWithAllCondNotMatch);
    }

    public static class MyClassHelper {
        public static boolean isCond1(MyClass myClass) {
            return myClass.value == 1;
        }

        public static boolean isCond2(MyClass myClass) {
            return myClass.value == 2;
        }
    }

    public static class MyClass {
        private final int value;

        public MyClass(int value) {
            this.value = value;
        }

        @Override
        public String toString() {
            return "MyClass{" +
                    "value=" + value +
                    '}';
        }
    }
}

samabcde
  • 6,988
  • 2
  • 25
  • 41