代码之家  ›  专栏  ›  技术社区  ›  Leviand

当实现谓词而不是布尔值时

  •  4
  • Leviand  · 技术社区  · 6 年前

    我正在读一本书 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())


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

    3 回复  |  直到 6 年前
        1
  •  6
  •   Peter Lawrey    6 年前

    我想你是指第二个例子

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

    这可能已经表明这种形式可能会使读者感到困惑。没有 static 你可以写 table.isUsable() Table::isUsable 但它不会像你想的那样。

    哪个是正确的实现?

    我更喜欢 表::可使用 因为它也可以用作 table.isUsable 例如。

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

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

    第二种形式更适用于操作谓词,例如谓词或(谓词)

    有什么大的区别吗?

    在这种情况下,使用流可能较慢,但更重要的是,更容易混淆。

    返回谓词的方法的一个优点是它可以添加到任何类中,例如,由于某种原因不能更改表。

        2
  •  4
  •   Eran    6 年前

    Predicate<Table> isUsable() 假设您总是需要在需要 Predicate<Table> 实例,这是一个限制。

    另一方面,有 boolean isUsable() 给你使用的灵活性 Table::isUsable 在哪里 谓词表 是必需的,或使用 表::可使用 作为某些其他功能接口(与该方法的签名匹配)的实现或直接调用 t.isUsable() 针对特定 Table 实例。因此,我发现这种选择更有用。

        3
  •  -1
  •   Ilya    6 年前
    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);
    
    推荐文章