【问题标题】:How to test Predicate with method reference inside forEach of java 8如何在java 8的forEach中使用方法引用测试谓词
【发布时间】:2020-01-29 06:05:50
【问题描述】:

我正在尝试 forEach 中的方法引用

private static void printConditionally8(List<Person> people, Predicate<Person> predicate) {
    people.forEach(p-> { if (predicate.test(p)){
        System.out.println("Print here");}
    });
}

上面工作正常,但我想使用方法参考使它更短,但是它给出了编译问题。有什么办法让它发生吗?

private static void printConditionally8(List<Person> people, Predicate<Person> predicate) {
    people.forEach({ if (predicate::test){
        System.out.println("Print here");}
     });
}

【问题讨论】:

标签: java lambda java-8 method-reference


【解决方案1】:

您应该能够在运行操作之前过滤列表:

people.stream().filter(predicate).forEach(p -> System.out.println("Print here"));

您不能使用if(predicate::test),因为if 采用布尔表达式(这里甚至不知道predicate::test 的类型 - 请查看 lambda 表达式的目标类型文档)。使其工作的唯一方法是调用 test() 方法,就像您在第一个 sn-p 中所做的那样。

【讨论】:

  • 这是完美的方法!!更简洁的是:people.stream().filter(predicate).forEach(System.out::println);
【解决方案2】:

我认为您以错误的方式使用方法引用概念。

方法引用是一种调用方法的漂亮语法,就好像它是一个 lambda(java 8+ 将完成所有转换):

这是一个例子:

public class Foo {



   private static void printConditionally8(List<Person>persons, Predicate<Person> f) {
      persons.stream().filter(f).forEach(p -> System.out.print(p + " is here"));
   }
   private static Boolean myFilter(Person p) {
      return p.age > 18; 
   }

   public static void main(String[] args) {
      List<Person> persons = ... // create a list of persons
      printConditionally8(persons, Foo::myFilter); 
   } 

}

注意主方法是如何真正调用printConditionally8的。它将引用传递给 myFilter 方法,就好像是一个“匿名类”——它实现了Predicate 接口。

【讨论】:

  • 我们这里不需要明确的 myFilter(Person p) 方法。可以直接传lambda printConditionally8(persons, p-> p.age > 18);
  • 当然可以,但假设问题在于难以掌握方法推理的概念,这就是我提供这样一个示例的原因
猜你喜欢
  • 1970-01-01
  • 2015-10-16
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-09
相关资源
最近更新 更多