Java 8 使用谓词或函数作为Java流过滤器有什么区别?

Java 8 使用谓词或函数作为Java流过滤器有什么区别?,java-8,java-stream,predicate,Java 8,Java Stream,Predicate,因此,假设我在流上使用一些随机过滤器,最直接的方法是直接输入谓词: x.stream().filter(e -> e % 2 == 0) 此外,我可以简单地进行引用并提前定义谓词: Predicate<Integer> isEven = e -> e % 2 == 0; ... x.stream().filter(isEven) 据我所知,谓词当然要有限得多,而函数可能有副作用等。但由于像Venkat Subramaniam这样的人使用后一种解决方案,我真的想知道:这

因此,假设我在流上使用一些随机过滤器,最直接的方法是直接输入谓词:

x.stream().filter(e -> e % 2 == 0)
此外,我可以简单地进行引用并提前定义谓词:

Predicate<Integer> isEven = e -> e % 2 == 0;
...
x.stream().filter(isEven)

据我所知,谓词当然要有限得多,而函数可能有副作用等。但由于像Venkat Subramaniam这样的人使用后一种解决方案,我真的想知道:这里的主要区别是什么

不!与方法引用相比,谓词并没有真正的限制!事实上,这些东西都是一样的

只需查看
filter()
函数签名:
filter(Predicate从构建可重用谓词库的角度来看,返回布尔值的函数库比静态最终谓词实例库更通用。为什么

考虑包含以下内容的库:

public static boolean isEven(int i) { return i -> i % 2 == 0; }
vs

public静态最终谓词是_偶数=i->i%2==0;
  • 如果库函数命名得好,它们的可读性会更好。在长时间缺席后重新访问代码时,扫描
    filter(MyLib::isEven)
    filter(i->i%2==0)
    filter(MyLib::isEven)
    更容易,而
    filter(MyLib.is\u)则不会
  • 如果您只想调用库函数而不是将其用作谓词,那么它更可读。
    MyLib.isEven(i)
    MyLib.IS_偶数.test(i)
  • 如果需要使用
    IntPredicate
    而不是
    Predicate
    番石榴
    Predicate
    、Apache Collections4
    Predicate
    等,使用库函数,您只需继续执行
    MyLib::isEven
    。对于
    静态最终谓词
    实例,您必须通过执行
    MyLib.IS来转换它_偶数::test
    (最终还是使用了方法引用)

同样的推理适用于所有函数类型。编写函数。它们可以应用于任何与简单方法引用的签名相匹配的函数类型。

两者都将返回一个过滤流。使用谓词(返回true或false的函数)更具可读性……以下是上述使用函数的简要说明

  public class Demo {

    public static Function<Integer, Predicate<Integer>> isGreaterThanNumberIamAboutToApply = pivot -> number -> number % pivot == 0;

    public static void main(String[] args) {


        List<Integer> myInts = Arrays.asList(new Integer[]{1, 2, 3, 5, 6, 7, 7})
                .stream()
                .filter(isGreaterThanNumberIamAboutToApply
                        .apply(3)).collect(Collectors.toList());

        myInts.forEach(x -> System.out.printf("%s\n", x));

    }

}
公共类演示{
公共静态函数大于numberiamabouttoapply=pivot->number->number%pivot==0;
公共静态void main(字符串[]args){
List myInts=Arrays.asList(新整数[]{1,2,3,5,6,7})
.stream()
.过滤器(大于可应用的数字)
.apply(3)).collect(Collectors.toList());
myInts.forEach(x->System.out.printf(“%s\n”,x));
}
}

我明白了,如果没有MR,我们只能定义谓词,而这些谓词的可重用性实际上是有限的。因此,这就引出了一个问题:什么是更干净的编写方式?使用MR、谓词还是实际语句本身?@AdHominem这取决于您的上下文。如果您不打算真正重用谓词,那么只需请使用一个简单的lambda表达式,但如果您要继续重用它,我建议您在一些utils类中创建一个静态谓词实例,而不创建方法本身
private static boolean isEven(Integer integer) {
return integer % 2 == 0;
}
...
x.stream().filter(MyClass::isEven)
e -> {
    //side effects here
    return e % 2 == 0;
}
public static boolean isEven(int i) { return i -> i % 2 == 0; }
public static final Predicate<Integer> IS_EVEN = i -> i % 2 == 0; 
  public class Demo {

    public static Function<Integer, Predicate<Integer>> isGreaterThanNumberIamAboutToApply = pivot -> number -> number % pivot == 0;

    public static void main(String[] args) {


        List<Integer> myInts = Arrays.asList(new Integer[]{1, 2, 3, 5, 6, 7, 7})
                .stream()
                .filter(isGreaterThanNumberIamAboutToApply
                        .apply(3)).collect(Collectors.toList());

        myInts.forEach(x -> System.out.printf("%s\n", x));

    }

}