[英]Method references not working in Java stream filter
我有一个包含一些字符串的列表,我想过滤这些列表,但是方法参考::startsWith 没有像我预期的那样工作。
private static final String KEY = "key=";
List<String> keyList = List.of("key=123", "value12", "value=34", "key=5678");
List<String> filtered = keyList.stream().filter(KEY::startsWith).collect(Collectors.toList());
List<String> filtered1 = keyList.stream().filter(e -> e.startsWith(KEY)).collect(Collectors.toList());
List<String> filtered2 = keyList.stream().filter("key="::startsWith).collect(Collectors.toList());
只有 filters1 具有预期的两个条目,其他列表为空。 为什么 KEY::startsWith 没有按预期工作?
你做错了。
.filter(KEY::startsWith)
意思是一样的
.filter(k->KEY.startsWith(k))
这将检查KEY
是否以要过滤的元素开头。
但是您想检查要过滤的元素是否以键开头。
.filter(k->k.startsWith(KEY))
如果您查看Java 语言规范,第 15.13 章,您可以看到:
实例方法的目标引用(第 15.12.4.1 节)可以由方法引用表达式使用 ExpressionName、Primary 或 super 提供,也可以稍后在调用方法时提供。 新的内部 class 实例(第 15.9.2 节)的直接封闭实例由 this 的词汇封闭实例(第 8.1.3 节)提供。
这意味着它将使用::
运算符左侧的变量作为 object 来调用startsWith
。
引用特定类型的任意 Object 的实例方法以下是引用特定类型的任意 object 的实例方法的示例:
String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; Arrays.sort(stringArray, String::compareToIgnoreCase);
方法引用
String::compareToIgnoreCase
的等效 lambda 表达式将具有形式参数列表 (String a, String b),其中 a 和 b 是用于更好地描述此示例的任意名称。 方法引用将调用方法a.compareToIgnoreCase(b)
。
KEY::startsWith
表示:
x -> KEY.startsWith(x)
因此,您正在检查key=
是否以key=123
等开头,这是错误的方法。 您应该检查key=123
是否以key=
= 开头。 "key="::startsWith
也是如此。
您不能在此处真正使用对startsWith
的方法引用。 如果在String
中有一个类似于isStartOf
的方法:
public boolean isStartOf(String other) {
return other.startsWith(this);
}
那么您可以使用KEY::isStartOf
,但我认为没有内置的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.