在Java8中,如何保证不重复投射?
In Java8, how to ensure repeated casting is not used?
我在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 as:
incompatible parameter types in lambda expression
如果我删除 str 的 String 前缀,那么我必须更改每个 str 在条件链中出现 ((String) str).startsWith("B") || ... 这确实很冗长。
发生这种情况是因为您将参数化 class Predicate
用作原始 class,而不是利用泛型。您应该将 Predicate
更改为 Predicate<T>
,然后您的代码将起作用,并且您可以删除 String
前缀。
Predicate
本质上类似于 Predicate<Object>
,因此您的 filter()
方法期望第二个参数是对 Object
进行操作的谓词。但是,您正试图传递 Predicate<String>
。由于 Predicate<String>
不是 Predicate<Object>
,您会收到编译错误。
将参数更改为 Predicate<T>
后,您的 lambda 表达式不再需要显式表示 String str
,因为只需输入 str
,它就会自动求值为 Predicate<String>
使用类型推断。
你只需要添加一个类型参数到Predicate
。
public static <T> void filter(List<T> items, Predicate<T> condition)
^^^
这允许类型检查器推断调用中的 lambda 表达式必须采用 String
参数。
但是如果您担心演员表的冗长,那么您将忽略 "elephant in the room"。
您不需要编写 12 行的自定义 filter
方法来执行此操作。 Stream
API 提供了大约 3 行所需的所有内容。
List <String> cities = Arrays.asList("Chennai", "New Delhi",
"Mumbai", "Pune", "Madurai", "Bhopal", "Bilaspur");
System.out.println(cities.stream()
.filter(str->str.startsWith("B") ||
str.startsWith("C") ||
str.startsWith("M"))
.collect(Collectors.joining(" ")));
filter
有标准的Stream::filter
方法。迭代由 stream()
完成,space 分隔字符串的组装由 joining
收集器完成。
我在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 as:
incompatible parameter types in lambda expression
如果我删除 str 的 String 前缀,那么我必须更改每个 str 在条件链中出现 ((String) str).startsWith("B") || ... 这确实很冗长。
发生这种情况是因为您将参数化 class Predicate
用作原始 class,而不是利用泛型。您应该将 Predicate
更改为 Predicate<T>
,然后您的代码将起作用,并且您可以删除 String
前缀。
Predicate
本质上类似于 Predicate<Object>
,因此您的 filter()
方法期望第二个参数是对 Object
进行操作的谓词。但是,您正试图传递 Predicate<String>
。由于 Predicate<String>
不是 Predicate<Object>
,您会收到编译错误。
将参数更改为 Predicate<T>
后,您的 lambda 表达式不再需要显式表示 String str
,因为只需输入 str
,它就会自动求值为 Predicate<String>
使用类型推断。
你只需要添加一个类型参数到Predicate
。
public static <T> void filter(List<T> items, Predicate<T> condition)
^^^
这允许类型检查器推断调用中的 lambda 表达式必须采用 String
参数。
但是如果您担心演员表的冗长,那么您将忽略 "elephant in the room"。
您不需要编写 12 行的自定义 filter
方法来执行此操作。 Stream
API 提供了大约 3 行所需的所有内容。
List <String> cities = Arrays.asList("Chennai", "New Delhi",
"Mumbai", "Pune", "Madurai", "Bhopal", "Bilaspur");
System.out.println(cities.stream()
.filter(str->str.startsWith("B") ||
str.startsWith("C") ||
str.startsWith("M"))
.collect(Collectors.joining(" ")));
filter
有标准的Stream::filter
方法。迭代由 stream()
完成,space 分隔字符串的组装由 joining
收集器完成。