我有一个程序可以分析某些属性的文本。代码的基本结构对于所有属性都是相同的,它只在一行中变化: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中工作?还有另一种方法吗?
由于
答案 0 :(得分:5)
以下是一个以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);
containsAttributeXYZ
和containsAttributeABC
是返回WebDataField
的{{1}}类的方法。或者您可以在不修改boolean
的情况下创建内联lambda。例如。 :
WebDataField
您不需要创建实现processFields(fields, w -> w.getFieldName().length() > 5);
答案 1 :(得分:1)
您无需创建新类来创建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 Tutorial。