谓词中的运算符作为lambda表达式中的参数

Nir*_*mal 2 java lambda predicate type-conversion java-8

我需要在lambda表达式中使用Predicate作为参数.我尝试了一个示例代码,但看到编译器错误.我看到编译器对不同的参数采用不同的谓词.所以Predicate参数n -> true and n -> false有效,但n -> n%4 == 0不起作用.

编译器错误是:

The operator % is undefined for the argument type(s) Object, int
Run Code Online (Sandbox Code Playgroud)

我修好了(请参阅下面的替换代码),但我问我是否应该修复它,为什么?我不确定我是否遗漏了一些基本的东西.

这是完整的代码:

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

public class PredicateAsArgumentInLambdaExpression {

        public static int add(List<Integer> numList, Predicate predicate) {
            int sum = 0;
            for (int number : numList) {
                if (predicate.test(number)) {
                    sum += number;
                }
            }
            return sum;
        }

        public static void main(String args[]){
            List<Integer> numList = new ArrayList<Integer>();
            numList.add(new Integer(10));
            numList.add(new Integer(20));
            numList.add(new Integer(30));       
            numList.add(new Integer(40));       
            numList.add(new Integer(50));

            System.out.println("Add Everything: "+add(numList, n -> true));
            System.out.println("Add Nothing: "+add(numList, n -> false));
//          System.out.println("Add Less Than 25: "+add(numList, n -> n < 25)); Compiler says: The operator < is undefined for the argument type(s) Object, int
            System.out.println("Add Less Than 25: "+add(numList, n -> Integer.valueOf((int)n) < Integer.valueOf("25")));
//          System.out.println("Add 4 Multiples: "+add(numList, n -> n % 4 == 0)); //Compiler says: The operator % is undefined for the argument type(s) Object, int
            System.out.println("Add 4 Multiples: "+add(numList, n -> Integer.valueOf((int)n) % Integer.valueOf("4")==0));
        }
}
Run Code Online (Sandbox Code Playgroud)

注释掉的代码是不起作用的,紧接着下面的行是替换代码.代码按原样运行,但我希望注释掉的代码应该有效!什么是java.util.function.Predicate中的Predicate不行?如果您找到答案,请提供规格页面的任何链接.

Kon*_*kov 5

发生的事情是你使用的是raw java.util.function.Predicate,test()方法看起来像:

public void test(Object o) { ... }
Run Code Online (Sandbox Code Playgroud)

这就是您遇到编译时错误的原因:参数类型是Object,数字运算符(<,>)不适用于该类型Object.

但是,如果使用java.util.function.Predicate带有type-parameter的泛型Integer,则该test()方法如下所示:

public void test(Integer i) { ... }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,数字运算符(>,<)对提供的参数类型(Integer)有效,并且不需要强制转换.

另外,我利用Java8中的Stream API缩短了方法实现:

public static int add(List<Integer> numList, Predicate<Integer> predicate) {
     return numList.stream().filter(predicate).mapToInt(i -> i).sum();
}
Run Code Online (Sandbox Code Playgroud)

让这个方法像这样实现,现在所有这些语句都是完全有效的:

System.out.println("Add Everything: "+add(numList, n -> true));
System.out.println("Add Nothing: "+add(numList, n -> false));
System.out.println("Add Less Than 25: "+add(numList, n -> n < 25));
System.out.println("Add 4 Multiples: "+add(numList, n -> n % 4 == 0));  
Run Code Online (Sandbox Code Playgroud)

  • @ user3320018,您在提供的代码段中没有任何流API,因此我们不太可能通过此问题帮助您解决此编译器错误. (2认同)