Java中的Streams无法识别此代码

时间:2017-11-26 11:02:39

标签: java lambda java-8 java-stream

我找到了以下代码段:

Function<Integer, Predicate<Integer>> smallerThan = x -> y -> y < x;
List<Integer> l = Arrays.asList(5, 6, 7, 23, 4, 5645,
    6, 1223, 44453, 60182, 2836, 23993, 1);

List<Integer> list2 = l.stream()
    .filter(smallerThan.apply(l.get(0)))
    .collect(Collectors.toList());

System.out.println(list2);

作为输出我收到:

[4, 1]

考虑到我们只传递一个参数smallerThan,此示例中的smallerThan.apply(l.get(0))函数如何工作?

3 个答案:

答案 0 :(得分:19)

smallerThanFunction,接受单个Integer并返回Predicate<Integer>Predicate<Integer>是一个接受单Integer的函数}并返回boolean)。

smallerThan.apply(l.get(0))会返回Predicate<Integer>,如下所示:

y -> y < l.get(0)

即。如果传递给它的输入小于true,则返回l.get(0)

当您将Predicate传递给filter时,您的Stream管道只会保留小于l.get(0)的元素。

您的管道可以重写为:

List<Integer> list2 = l.stream()
    .filter(y -> y < l.get(0))
    .collect(Collectors.toList());

由于l.get(0)5,您的管道会返回原始列表中小于5的所有元素。

答案 1 :(得分:13)

这叫做&#34; currying&#34;例如,在Java 8之前也可以通过匿名类来实现,但它更加冗长。归根结底,它是一个Function,它返回一个Function而在Java中尚未传播,但在其他功能语言中,它被大量使用。

答案 2 :(得分:8)

函数smallerThan接受一个数字并返回一个Predicate对象,在这种情况下,我们将这个谓词应用于流的每个元素。

因此,l.get(0)将检索列表l的第一个值(5),然后我们将其传递给smallerThan函数,此函数返回一个谓词条件y -> y < x;读取为“给定数字,如果小于5则返回true”因此输出为[4, 1]