I need to use Predicate as argument in lambda expression. I tried an example code but seeing compiler error.
I see that the compiler is treating the same Predicate differently for different arguments. So Predicate arguments n -> true and n -> false
works but n -> n%4 == 0
doesn't work.
The compiler error is:
The operator % is undefined for the argument type(s) Object, int
I fixed it (see the replacement code below) but I am asking should I have to fix it and why? I am not sure if I am missing something basic.
Here is the complete code:
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));
}
}
Commented out code are what's not working and the line immediately below each is the replacement code. The code works as is and as expected but I was expecting that the commented out code should have worked! What's is it that isn't ok with Predicate in java.util.function.Predicate here?. Please provide any link for specification page if you find the answer in.
What is happening is that you're using a raw
java.util.function.Predicate
, on which thetest()
method would look like:This is why you get a compile-time error: the argument type is
Object
and the numeric operators (<
,>
) are not applicable for the typeObject
.However, if you use a generic
java.util.function.Predicate
with type-parameter ofInteger
, thetest()
method would look like:In this case, the numeric operators (
>
,<
) are valid for the provided argument type (Integer
) and there's no need of casts.Also, I've taken advantage of the Stream API in Java8 to shorten your method implementation:
Having the method implemented like this, now all these statements will be perfectly valid: