方法引用和链式谓词

时间:2015-05-20 18:08:27

标签: java java-8 predicate java-stream method-reference

我正在尝试使用方法引用来压缩我的代码。以下是我要改进的一句话:

assertThat("only true & false strings allowed",
        records.stream().map(Record::getType)
        .allMatch(s -> "true".equals(s) || "false".equals(s)));

使用方法参考可能会更好:

assertThat("only true & false strings allowed",
       records.stream().map(Record::getType).allMatch("true"::equals));

但是,无论如何我可以在谓词中添加“false”吗?

3 个答案:

答案 0 :(得分:5)

我所知道的String类或JDK中没有与您的Predicate等效的方法。你可以自定义

public static boolean match(String arg) {
    return "true".equals(arg) || "false".equals(arg);
}

并使用它

assertThat("only true & false strings allowed",
   records.stream().map(Record::getType).allMatch(Example::match);

或者您可以将Pattern正则表达式用作Predicate

assertThat("only true & false strings allowed",
   records.stream().map(Record::getType)
          .allMatch(Pattern.compile("^(false|true)$").asPredicate()));

并且,正如Holger in comments所建议的那样,您可以使用

.allMatch(Arrays.asList("true", "false")::contains)

或从Set创建的类似内容。

答案 1 :(得分:0)

您可以使用PredicatesPredicate.and()Predicate.or()链接在一起,但首先必须强制对谓词进行方法引用

Predicate<String> trueTest = "true"::equals;

然后你可以在比赛中进行链接

records.stream().map(Record::getType).allMatch( trueTest.or("false"::equals));

或在流外创建谓词

Predicate<String> trueTest = "true"::equals;
Predicate<String> trueOrFalseTest = trueTest.or("false"::equals);


records.stream().map(Record::getType).allMatch( trueOrFalseTest );

无论如何,我发现其中任何一个都比原始代码更易读。

答案 2 :(得分:0)

它不是单行,但您可以在.or()上使用Predicate方法:

Predicate<String> isTrue = "true"::equals;
Predicate<String> isFalse = "false"::equals;

assertThat("only true & false strings allowed",
   records.stream().map(Record::getType).allMatch(isTrue.or(isFalse)))