我需要在lambda表达式中使用Predicate作为参数。我尝试了一个示例代码,但看到了编译错误。
我看到编译器对不同的参数采用不同的谓词。所以谓词参数n -> true and n -> false
有效但n -> n%4 == 0
无效。
编译错误是:
The operator % is undefined for the argument type(s) Object, int
我修好了(看下面的替换代码),但我问我是否应该修复它,为什么?我不确定我是否遗漏了一些基本的东西。
以下是完整的代码:
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));
}
}
注释掉的代码不起作用,紧接着下面的代码就是替换代码。代码按原样运行,但我希望注释掉的代码应该有效!对于java.util.function.Predicate中的Predicate来说,这是不是没有问题?如果您找到答案,请提供规格页面的任何链接。
答案 0 :(得分:5)
正在发生的事情是您正在使用原始 java.util.function.Predicate
,<Directory /var/www/secundary.mysite.com/web>
Options -Includes +ExecCGI
AllowOverride All
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/bundles(.*)$ [NC]
RewriteRule ^.*$ - [F]
</Directory>
方法看起来像这样:
test()
这就是您遇到编译时错误的原因:参数类型为public void test(Object o) { ... }
,数字运算符(Object
,<
)不适用于{{1}类型}。
但是,如果您使用类型参数为>
的通用java.util.function.Predicate
,Object
方法将如下所示:
Integer
在这种情况下,数字运算符(test()
,public void test(Integer i) { ... }
)对提供的参数类型(>
)有效,并且不需要强制转换。
另外,我利用Java8中的Stream API缩短了方法实现:
<
实现这样的方法,现在所有这些语句都是完全有效的:
Integer
答案 1 :(得分:1)
您在add
方法中忽略了通用参数。如果您从常规Predicate
切换到Predicate<Integer>
,则n
会在操作前自动转换为Integer
。
简而言之,而不是:
public static int add(List<Integer> numList, Predicate predicate) {
你应该尝试:
public static int add(List<Integer> numList, Predicate<Integer> predicate) {
之后,您之前的代码:
n -> Integer.valueOf((int)n) < Integer.valueOf("25")
n -> Integer.valueOf((int)n) % Integer.valueOf("4")==0
可以简单地
n -> n < 25
n -> n % 4 == 0
另外效率更高。
这只是一个匹配方法期望与您提供的内容相关的问题。由于没有通用术语,Java希望Predicate
默认接收类型Object
,并且由于Integer
扩展Object
,因此它假定这是您传递的类型。有了它,它期望Integer
,并且公开了与Integer
相关的所有方法和运算符。
这是一个在调用方法之前发生的有点不可见的操作,这就是为什么你的警告是在lambda操作上而不是在方法中。
祝你好运!