The target type of this expression must be a functional interface

后端 未结 3 723
南笙
南笙 2020-12-31 06:11

I created a function to filter with multiple predicates for which I perform a logical AND for them:

@SafeVarargs
public static  Stream filt         


        
相关标签:
3条回答
  • 2020-12-31 06:16

    Both Netbeans and Eclipse have a number of bugs in the area of parsing lambda expressions in Java. They are slowly getting fixed but, until they are, the best workarounds I have found are: 1. declare types 2. if that doesn't work, use a block 3. if that doesn't work, create an anonymous object that implements the predicate/function etc.

    These make your code messier but they are necessary in a number of situations.

    0 讨论(0)
  • 2020-12-31 06:16

    Sometimes Eclipse needs a good ol' clean and rebuild of all projects and the problem goes away.

    0 讨论(0)
  • 2020-12-31 06:42

    This is a corner case for the compiler. In order to determine whether it should apply varargs wrapping of arguments into an array or simply pass an array, it needs to know the type of the last argument, however, in the case of a lambda expression it needs the invoked method signature to determine the type. But it’s clear what should happen as a lambda expression can never be an array type and so, javac compiles it without problems.

    One acceptable work-around would be to overload the method:

    @SafeVarargs
    public static <T> Stream<T> filter(Stream<T> source, Predicate<T>... predicates) {
        return source.filter(
            Arrays.stream(predicates).reduce(predicates[0], Predicate::and));
    }
    public static <T> Stream<T> filter(Stream<T> source, Predicate<T> predicate) {
        return source.filter(predicate);
    }
    

    This would be an an acceptable work-around as it does not require any changes on the calling side while improving the efficiency for the single-arg case at the same time.


    Please note that your varargs method allows zero arguments but will fail if called that way. So you should either, add another overload:

    public static <T> Stream<T> filter(Stream<T> source) {
        return source;
    }
    

    or make the method safe for the zero argument case:

    @SafeVarargs
    public static <T> Stream<T> filter(Stream<T> source, Predicate<T>... predicates) {
        return Arrays.stream(predicates).reduce(Predicate::and)
                     .map(source::filter).orElse(source);
    }
    
    0 讨论(0)
提交回复
热议问题