繁体   English   中英

Java 8中的谓词

[英]Predicates in Java 8

我有一个程序来分析某些属性的文本。 代码的基本结构对于所有属性都是相同的,它只在一行中变化: webDataField.containsAttributeXYZ(); 如下所示:

for (int index = 0; index < fields.size(); index++) {
    WebDataField webDataField = fields.get(index);
    boolean expectedCondition = webDataField.containsAttributeXYZ(); // Varies at this line..

    Double score = evaluateBooleanCondition(actualCondition, expectedCondition);

    WebDataFields fieldName = webDataField.getFieldName();
    ...
}

而不是为每个条件编写相同的代码(并在代码中重复自己),我想编写代码的主体一次,并将条件(计算结果为true或false)传递给方法。

我是Java Predicate新手,但如果我理解正确,这正是Java中谓词的功能。

这是否迫使我在自己的类中编写每个条件,然后让该类实现Predicate接口?

如果是这样,该函数(先前在包含类似函数的类中声明)将需要转换为如下所示:

class ContainsAttributeXYZ implements Predicate<Boolean>

这会导致代码迷失方向并触发程序中类的数量大量增加(因为每个函数都需要转换为类)

或者我误解了Predicates如何在Java中工作? 还有另一种方法吗?

谢谢

这是一个以Predicate为参数的示例方法:

void processFields(List<WebDataField> fields, Predicate<WebDataField> predicate) {
    for (WebDataField webDataField : fields) {
        boolean expectedCondition = predicate.test(webDataField);
    }
}

你可以通过传递方法引用来调用它,如下所示:

processFields(fields, WebDataField::containsAttributeXYZ);
processFields(fields, WebDataField::containsAttributeABC);

containsAttributeXYZcontainsAttributeABC是返回booleanWebDataField类的方法。 或者,您可以在不修改WebDataField情况下创建lambda内联。 例如:

processFields(fields, w -> w.getFieldName().length() > 5);

您不需要创建实现Predicate的类

您不需要创建新类来创建Predicate 这是因为Java 8添加了一个lambda语法,您可以将其视为匿名内部类的简写,仅使用一个方法实现接口。 这是一个例子:

Predicate<Boolean> containsXYZ = b -> {
    return !b;
};

这相当于:

Predicate<Boolean> containsXYZ = new Predicate<Boolean>() {
    public boolean test(Boolean b) {
        return !b;
    }
};

如果您的谓词只返回单个表达式的结果,则可以缩短为:

Predicate<Boolean> containsXYZ = b -> !b;

或者,函数可以是对方法的引用:

Predicate<Boolean> containsXYZ = MyClass::myMethod; // for static methods, or
Predicate<Boolean> containsXYZ = this::myMethod; // for instance methods

这是一个单行谓词,如果输入为false,则返回true,反之亦然。 现在,对于您的用例,您可能需要以下内容:

static void checkAttributes(Predicate<WebDataField> containsAttributeXYZ) {
    for (WebDataField webDataField : fields) {
        boolean expectedCondition = containsAttributeXYZ.test(webDataField);
        Double score = evaluateBooleanCondition(actualCondition, expectedCondition);
        WebDataFields fieldName = webDataField.getFieldName();

        ...
    }
}

有关lambda如何工作的详细说明,请阅读Java教程

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM