我正在阅读not related thread,当我阅读评论时:每当我发现自己需要多行lambda时,我会将行移至私有方法并传递方法引用而不是lambda。
我当时在问:实施此行为的正确方法是什么?使用评论中发布的布尔方法还是谓词?
示例:
假设我要检查Table
是否可用,其中可用表示isClean
,isEmpty
,hasChair
。
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())
哪个是正确的实现?为什么选择一个而不是另一个?有什么大不同吗?
答案 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));
}