簡體   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