当实现谓词而不是布尔值时
When implement Predicate instead of boolean
我正在阅读 ,当我看到评论时: 任何时候我发现自己需要一个多行 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())
哪个是正确的实施方式?为什么选择一个而不是另一个?有什么大的不同吗?
我想你指的是第二个例子
public static Predicate<Table> isUsable(){
return table -> table.isEmpty() && table.isClean() && table.hasChair();
}
这可能已经表明这种形式很可能会混淆 reader。没有 static
你可以写 table.isUsable()
或 Table::isUsable
但它不会像你想的那样。
Which is the correct implementation?
我更喜欢 Table::isUsable
,因为它也可以用作实例的 table.isUsable
。
Why choose one instead of other?
我觉得第一个例子更自然,不那么令人困惑。
第二种形式对于操作谓词更有用,例如Predicate.or(谓词)
Is there any big difference?
在这种情况下,使用 Stream 可能会更慢,但更重要的是,更容易混淆。
返回谓词的方法的一个优点是它可以添加到任何 class 例如由于某些原因,您无法更改 Table。
拥有 Predicate<Table> isUsable()
假设您始终需要在需要 Predicate<Table>
实例的地方使用该逻辑,这是一个限制。
另一方面,拥有 boolean isUsable()
可以让您灵活地使用 Table::isUsable
需要 Predicate<Table>
,或者使用 Table::isUsable
作为其他功能的实现接口(匹配该方法的签名)或直接调用 t.isUsable()
特定的 Table
实例。因此我发现这个替代方案更有用。
static List<Predicate<Table>> predicateList = Arrays.asList(Table::hasChair, Table::isClean);
static boolean isUsable(Table table) {
return predicateList.stream().allMatch(p -> p.test(table));
}
使用可用:
List<Table> tablesList = ...
Stream<Table> usableTables = tablesList.stream().filter(Table::isUsable);
我正在阅读
我在问:实现这种行为的正确方法是什么?使用评论中发布的布尔方法,还是使用谓词?
示例:
假设我想检查 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())
哪个是正确的实施方式?为什么选择一个而不是另一个?有什么大的不同吗?
我想你指的是第二个例子
public static Predicate<Table> isUsable(){
return table -> table.isEmpty() && table.isClean() && table.hasChair();
}
这可能已经表明这种形式很可能会混淆 reader。没有 static
你可以写 table.isUsable()
或 Table::isUsable
但它不会像你想的那样。
Which is the correct implementation?
我更喜欢 Table::isUsable
,因为它也可以用作实例的 table.isUsable
。
Why choose one instead of other?
我觉得第一个例子更自然,不那么令人困惑。
第二种形式对于操作谓词更有用,例如Predicate.or(谓词)
Is there any big difference?
在这种情况下,使用 Stream 可能会更慢,但更重要的是,更容易混淆。
返回谓词的方法的一个优点是它可以添加到任何 class 例如由于某些原因,您无法更改 Table。
拥有 Predicate<Table> isUsable()
假设您始终需要在需要 Predicate<Table>
实例的地方使用该逻辑,这是一个限制。
另一方面,拥有 boolean isUsable()
可以让您灵活地使用 Table::isUsable
需要 Predicate<Table>
,或者使用 Table::isUsable
作为其他功能的实现接口(匹配该方法的签名)或直接调用 t.isUsable()
特定的 Table
实例。因此我发现这个替代方案更有用。
static List<Predicate<Table>> predicateList = Arrays.asList(Table::hasChair, Table::isClean);
static boolean isUsable(Table table) {
return predicateList.stream().allMatch(p -> p.test(table));
}
使用可用:
List<Table> tablesList = ...
Stream<Table> usableTables = tablesList.stream().filter(Table::isUsable);