方法引用在 Java 流过滤器中不起作用
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());
只有 filtered1 有预期的两个条目,其他列表为空。为什么 KEY::startsWith 没有按预期工作?
你做错了。
.filter(KEY::startsWith)
与
的含义相同
.filter(k->KEY.startsWith(k))
这会检查 KEY
是否以要过滤的元素开头。
但您想检查要过滤的元素是否以键开头。
.filter(k->k.startsWith(KEY))
如果你查看 the Java Language Specification, chapter 15.13,你可以看到:
The target reference of an instance method (§15.12.4.1) may be provided by the method reference expression using an ExpressionName, a Primary, or super, or it may be provided later when the method is invoked. The immediately enclosing instance of a new inner class instance (§15.9.2) is provided by a lexically enclosing instance of this (§8.1.3).
这意味着它将使用::
运算符左侧的变量作为对象来调用startsWith
。
这在the method references page of the Java Tutorials中也有解释:
Reference to an Instance Method of an Arbitrary Object of a Particular Type
The following is an example of a reference to an instance method of an arbitrary object of a particular type:
String[] stringArray = { "Barbara", "James", "Mary", "John",
"Patricia", "Robert", "Michael", "Linda" };
Arrays.sort(stringArray, String::compareToIgnoreCase);
The equivalent lambda expression for the method reference String::compareToIgnoreCase
would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the method 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
,但我认为没有内置的方法。
我有一个包含一些字符串的列表,我想过滤这些列表,但是方法引用 ::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());
只有 filtered1 有预期的两个条目,其他列表为空。为什么 KEY::startsWith 没有按预期工作?
你做错了。
.filter(KEY::startsWith)
与
的含义相同.filter(k->KEY.startsWith(k))
这会检查 KEY
是否以要过滤的元素开头。
但您想检查要过滤的元素是否以键开头。
.filter(k->k.startsWith(KEY))
如果你查看 the Java Language Specification, chapter 15.13,你可以看到:
The target reference of an instance method (§15.12.4.1) may be provided by the method reference expression using an ExpressionName, a Primary, or super, or it may be provided later when the method is invoked. The immediately enclosing instance of a new inner class instance (§15.9.2) is provided by a lexically enclosing instance of this (§8.1.3).
这意味着它将使用::
运算符左侧的变量作为对象来调用startsWith
。
这在the method references page of the Java Tutorials中也有解释:
Reference to an Instance Method of an Arbitrary Object of a Particular Type The following is an example of a reference to an instance method of an arbitrary object of a particular type:
String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; Arrays.sort(stringArray, String::compareToIgnoreCase);
The equivalent lambda expression for the method reference
String::compareToIgnoreCase
would have the formal parameter list (String a, String b), where a and b are arbitrary names used to better describe this example. The method reference would invoke the methoda.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
,但我认为没有内置的方法。