【问题标题】:Why chaining is not working when passed as lambdas in predicate?为什么在谓词中作为 lambdas 传递时链接不起作用?
【发布时间】:2021-09-03 23:47:24
【问题描述】:

我是函数式编程的新手。 我想了解我在这里缺少哪个概念。

    Stream<Employee> stream1 = getEmployeeListOne().stream();
    Stream<Employee> stream2 = getEmployeeListTwo().stream();
    Predicate<Employee>predicate=x->x.getFirstName().startsWith("L");
    //Below line is compile time error
    List<Employee>list=stream1.filter((x->x.getFirstName().startsWith("L")).or(x->x.getLastName().startsWith("L"))).collect(Collectors.toList());
    //Below line works well 
    //List<Employee>list2=stream1.filter(predicate.or(x->x.getLastName().startsWith("L"))).collect(Collectors.toList());
    

它只是说这里不需要 lambda 表达式

【问题讨论】:

  • 到底是什么问题? --- 在给出的代码中,stream1.filter(...) 被调用了两次。 Streams 是一次性资源,所以一旦被消费一次,就“空”了。
  • @Turing85 即使我评论最后一行,也是编译错误。我没有在这里发表评论。谢谢我已经更新了问题。
  • 请edit问题并添加编译错误。
  • 因为在另一个示例中,我们使用了 Predicate,由 lambda 初始化。在第一个示例中,我们使用“原始”lambda。它还不是Predicate,只是一个 lambda。
  • @Bergi 当然,我们可以转换 lambda:((&lt;Type-we-need&gt;) &lt;lambda-expression&gt;)。

标签: java-8 functional-programming


【解决方案1】:

Predicate 具有 or() 方法。
lambda 不会。

如果您将 lambda 分配给 Predicate 类型的变量,则您正在实现 Predicate 的单个未实现方法 test(),它只有一个 or() 方法。

【讨论】:

    【解决方案2】:

    这就是我尝试的方法,在方法中提取类似的测试条件,使谓词返回复合条件的布尔值。

    如果你写的话,链接确实有效

    final Predicate<Employee> onlyEmpNameStarsWithL = employee -> nameStartsWithL(employee.firstName);// || nameStartsWithL(employee.lastName);
    

    然后使用下面的完整代码:

    List<Employee> allEmployeeWithLInName = employeeStream.filter(Objects::nonNull)
                    .filter(onlyEmpNameStarsWithL.or(e -> nameStartsWithL(e.lastName)))
                    .collect(Collectors.toList());
    
            allEmployeeWithLInName.forEach(System.out::println);
    

    或完整的其他方法

    final Predicate<Employee> onlyEmpNameStarsWithL = 
    employee -> nameStartsWithL(employee.firstName) || nameStartsWithL(employee.lastName);
    

    辅助方法

        static boolean nameStartsWithL(String name) {
            return name != null && name.startsWith("L");
        }
    
    

    完整的源代码

    package examples;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.Objects;
    import java.util.function.Predicate;
    import java.util.stream.Collectors;
    import java.util.stream.Stream;
    
    class Employee {
        String firstName;
        String lastName;
    
        public Employee(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "firstName='" + firstName + '\'' +
                    ", lastName='" + lastName + '\'' +
                    '}';
        }
    }
    
    public class LambdaPredicate {
        static boolean nameStartsWithL(String name) {
            return name != null && name.startsWith("L");
        }
    
        public static void main(String[] args) {
            List<Employee> employeeList = Arrays.asList(
                    new Employee("A", "P"),
                    new Employee("B", "L"),
                    null,
                    new Employee("C", "Q"),
                    new Employee("L", "I"),
                    new Employee("L", "L")
            );
    
            final Predicate<Employee> onlyEmpNameStarsWithL = employee -> nameStartsWithL(employee.firstName) || nameStartsWithL(employee.lastName);
            Stream<Employee> employeeStream = employeeList.stream();
    
            List<Employee> allEmployeeWithLInName = employeeStream.filter(Objects::nonNull)
                    .filter(onlyEmpNameStarsWithL)
                    .collect(Collectors.toList());
    
            allEmployeeWithLInName.forEach(System.out::println);
        }
    }
    
    

    输出

    Employee{firstName='B', lastName='L'}
    Employee{firstName='L', lastName='I'}
    Employee{firstName='L', lastName='L'}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 2011-07-08
      • 2011-10-26
      • 1970-01-01
      • 2012-03-27
      相关资源
      最近更新 更多