如何解决使用 Stream#takeWhile 应用模式#astMatchPredicate
我尝试将模式中的预测应用于字符串流:
final var someString = "first\nsecond\nthird"
final var myPattern = java.util.regex.Pattern.compile("second");
final var sb = new java.lang.StringBuilder();
someString.lines()
.takeWhile(not(myPattern::asMatchPredicate))
.forEachOrdered(sb::append)
;
但是编译器拒绝了这个错误:
method asMatchPredicate in class java.util.regex.Pattern cannot be applied to given types
required: no arguments
found: java.lang.String
reason: actual and formal argument lists differ in length
但是为什么呢?谓词接受一个字符串 (Predicate<String>
),而 takeWhile
方法需要一个 Predicate<? extends String>
。
解决方法
另一种方法是否定正则表达式模式,即使用 ^((?!second).)*$
作为正则表达式模式。
演示:
class Main {
public static void main(String[] args) {
final var someString = "first\nsecond\nthird";
final var myPattern = java.util.regex.Pattern.compile("^((?!second).)*$");
final var sb = new java.lang.StringBuilder();
someString.lines().takeWhile(myPattern.asPredicate()).forEachOrdered(sb::append);
System.out.println(sb);
}
}
输出:
first
正则表达式解释为 regex101:
,实际上,您正在执行以下操作:
Predicate<String> predicate = myMatcher::asMatchPredicate;
方法引用意味着您正在尝试实现自己的 Predicate<String>
,而不是使用 Pattern#asMatchPredicate()
返回的方法。这在这种情况下不起作用,原因有两个:
-
Pattern#asMatchPredicate()
方法不接受任何参数,但Predicate#test(T)
方法接受单个参数。 -
Pattern#asMatchPredicate()
方法返回Predicate<String>
,但Predicate#test(T)
方法返回boolean
。
由于 Pattern#asMatchPredicate()
方法已经返回一个 Predicate<String>
,因此没有理由在此处使用方法引用——只需否定返回值即可。换句话说,您可以执行以下任一操作:
.takeWhile(Predicate.not(myMatcher.asMatchPredicate()))
或者:
.takeWhile(myMatcher.asMatchPredicate().negate())
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。