我在Java中具有以下过滤器功能:
public static <T> void filter(List<T> items, Predicate condition)
{
System.out.print("\t");
for(T element : items)
{
if (condition.test(element))
{
System.out.print(element + " ");
}
}
System.out.println("");
}
我尝试称其为:
List <String> cities = Arrays.asList("Chennai", "New Delhi",
"Mumbai", "Pune", "Madurai", "Bhopal", "Bilaspur");
filter(cities, (String str)->str.startsWith("B") ||
str.startsWith("C") ||str.startsWith("M"));
但是,我得到以下错误,指向String str为:
incompatible parameter types in lambda expression
如果我将字符串前缀删除为str,则必须将条件链中每个出现的str更改为((String)str).startsWith(“ B”)|| ...固然很冗长。
This is happening because you're using the parameterized class
Predicate
as a raw class, instead of leveraging generics. You should changePredicate
toPredicate<T>
, and then your code will work, and you can remove theString
prefix.Predicate
is essentially likePredicate<Object>
, so yourfilter()
method expects the second argument to be a predicate that operates onObject
s. However, you're attempting to pass aPredicate<String>
instead. Since aPredicate<String>
isn't aPredicate<Object>
, you're getting that compile error.Once you change the parameter to
Predicate<T>
, your lambda expression no longer needs to explicitly sayString str
, since by just puttingstr
it will automatically evaluate to aPredicate<String>
using type inference.You just need to add a type parameter to
Predicate
.This allows the type checker to infer that the lambda expression in the call must take a
String
parameter.But you don't need to write a custom
filter
method to do this.The
filter
there is the standardStream::filter
method. The iteration is done bystream()
and the assembly of a space-separated string is done by thejoining
collector.