Search code examples
javagenericsjava-8functional-interface

Generic declaration for Java Stream::*Match operations


I would like to create a generic test() function to demonstrate the Stream operations allMatch, anyMatch, and noneMatch. It might look something like this (which doesn't compile):

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

public class Tester {
    void test(Function<Predicate<Integer>, Boolean> matcher, int val) {
        System.out.println(
            Stream.of(1,2,3,4,5).matcher(n -> n < val));
    }
    public static void main(String[] args) {
        test(Stream::allMatch, 10);
        test(Stream::allMatch, 4);
        test(Stream::anyMatch, 2);
        test(Stream::anyMatch, 0);
        test(Stream::noneMatch, 0);
        test(Stream::noneMatch, 5);
    }
}

(I think) my challenge is in defining matcher which probably needs to be a generic rather than the way I do it here. I'm also not sure if it's possible to make the calls I show here in main().

I'm not even sure this can be done, so I'd appreciate any insights.


Solution

  • The following works:

    static void test(
          BiPredicate<Stream<Integer>, Predicate<Integer>> bipredicate, int val) {
        System.out.println(bipredicate.test(
             IntStream.rangeClosed(1, 5).boxed(), n -> n < val));
    }
    
    public static void main(String[] args) {
        test(Stream::allMatch, 10);
        test(Stream::allMatch, 4);
        test(Stream::anyMatch, 2);
        test(Stream::anyMatch, 0);
        test(Stream::noneMatch, 0);
        test(Stream::noneMatch, 5);
    }
    

    ...but if the point is to demonstrate what these things do, you'd probably be better off writing the more straightforward

    System.out.println(IntStream.rangeClosed(1, 5).allMatch(n -> n < 10));
    

    ..etcetera, which is a lot easier to read.