方法引用和链式谓词

Method reference and chained predicate

我正在尝试使用方法引用来压缩我的代码。这是我正在努力改进的一行:

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" 到谓词吗?

据我所知,String class 或 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()));

而且,正如 所建议的,您可以使用

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

或从 Set 创建的类似内容。

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

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

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

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

或者在流外创建一个Predicate

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


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

总之,我发现没有哪一个比您的原始代码更清晰。

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

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)))