在实现谓词而不是布尔值

时间:2018-10-22 07:52:38

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

我正在阅读not related thread,当我阅读评论时:每当我发现自己需要多行lambda时,我会将行移至私有方法并传递方法引用而不是lambda。

我当时在问:实施此行为的正确方法是什么?使用评论中发布的布尔方法还是谓词?


示例: 假设我要检查Table是否可用,其中可用表示isCleanisEmptyhasChair

class Table{
    public boolean hasChair(){...}
    public boolean isClean(){...}
    public boolean isEmpty(){...}
}

我可以通过两种方式对列表List<Table> tablesList = Arrays.asList(table1,table2,table3,table4);进行过滤测试:第一种是布尔值:

public boolean isUsable(){
    return hasChair() && isClean() && isEmpty();
}

并与tablesList.stream().filter(Table::isUsable)

一起使用

第二种方法是谓词:

public Predicate<Table> isUsable(){
    return table -> table.isEmpty() && table.isClean() && table.hasChair();
}

可与tablesList.stream().filter(isUsable())

一起使用

哪个是正确的实现?为什么选择一个而不是另一个?有什么大不同吗?

3 个答案:

答案 0 :(得分:6)

我想你的意思是第二个例子

public static Predicate<Table> isUsable(){
    return table -> table.isEmpty() && table.isClean() && table.hasChair();
}

可能已经暗示这种形式可能会使读者感到困惑。如果没有static,您可以写table.isUsable()Table::isUsable,但不会如您所愿。

  

哪个是正确的实现?

我更喜欢Table::isUsable,因为它也可以用作实例的table.isUsable

  

为什么选择一个而不是另一个?

我觉得第一个例子更自然,更容易混淆。

第二种形式在处理谓词时更有用,例如Predicate.or(Predicate)

  

有什么大不同吗?

在这种情况下,使用Stream可能会更慢,但更重要的是,更容易造成混淆。

该方法返回谓词的一个优点是可以将其添加到任何类中,例如您由于某种原因无法更改表格。

答案 1 :(得分:4)

具有Predicate<Table> isUsable()的前提是您始终要求在需要Predicate<Table>实例的地方使用该逻辑,这是一个限制。

另一方面,拥有boolean isUsable()可让您灵活地在需要Table::isUsable的地方使用Predicate<Table>或将Table::isUsable用作其他功能接口的实现( (与该方法的签名匹配)或直接为特定t.isUsable()实例调用Table。因此,我发现这种替代方法更有用。

答案 2 :(得分:-1)

chart.js

使用isUsable:

static List<Predicate<Table>> predicateList = Arrays.asList(Table::hasChair, Table::isClean);

static boolean isUsable(Table table) {
    return predicateList.stream().allMatch(p -> p.test(table));
}