【问题标题】:Understanding java Stream.limit() operation理解 java Stream.limit() 操作
【发布时间】:2018-10-25 09:40:28
【问题描述】:

我在学习 Stream.limit() 说:

返回由该流的元素组成的流,截断长度不超过 maxSize。

这可以理解为:

Stream.of(1,2,3,4,5,6,7,8)
    .limit(3)
    .forEach(i -> {
        System.out.print(i + ",");
    });  //prints: 1,2,3,

但是当与其他流方法一起使用时,它具有批量处理元素的效果:

Stream.of(1,2,3,4,5,6,7)
    .filter(i -> {
        System.out.println("Filtering "  + i + ": " + (i%2 == 0));
        return i%2 == 0;
    })
    .map(i-> {
        System.out.println("Mapping " + i + " to " + i*i);
        return i*i;
    })
    .limit(2)
    .forEach(i -> System.out.println("---> " + i));

打印:

Filtering 1: false
Filtering 2: true
Mapping 2 to 4
---> 4
Filtering 3: false
Filtering 4: true
Mapping 4 to 16
---> 16

在这里,您可以看到元素以 2 个为单位进行处理。

我有以下疑问:

  1. 为什么它不只处理前两个元素 1 和 2?也就是为什么输出不只是:

     Filtering 1: false
     Filtering 2: true
     Mapping 2 to 4
     ---> 4
    
  2. 为什么它没有处理最后四个元素 5、6、7 和 8 并打印以下内容?:

     Filtering 5: false
     Filtering 6: true
     Mapping 6 to 36
     ---> 36
     Filtering 7: false
     Filtering 8: true
     Mapping 8 to 64
     ---> 64
    

【问题讨论】:

  • 它们不是以两个为一组进行处理的。它们被逐个处理,但由于第一个和第三个被过滤器拒绝,它们没有被映射,即它们没有传递给管道的下一个操作,即映射函数。
  • 这取决于你的限价指令放置在哪里。
  • @eric.v 喜欢吗?还有其他例子吗?
  • 我推荐阅读this answer,然后想象你在管道中插入一个“让最多n个元素”阶段,一次在开始,一次在结束......

标签: java functional-programming java-stream


【解决方案1】:
  1. 12 均已处理。 1 是奇数,因此 filter 将其从流管道中删除。 2 是偶数并经过整个流管道,导致 4forEach 中打印出来。

  2. 流本质上是惰性的。由于您使用了limit(2),因此只有两个元素可以通过limit 管道步骤。 24 遍历整个流管道,导致 416forEach 中打印出来。

limit() 是短路状态中间操作,根据docs

limit(n) 或 findFirst() 等短路操作可以让无限流的计算在有限时间内完成。

...

此外,某些操作被视为短路操作。如果在呈现无限输入时,中间操作可能会产生有限流,则它是短路的。如果一个终端操作在有无限输入时可能会在有限时间内终止,那么它就是短路的。在管道中进行短路操作是无限流处理在有限时间内正常终止的必要条件,但不是充分条件。

【讨论】:

  • 为什么 6 和 8 没有通过限制?事实上,似乎 5、6、7 和 8 甚至都没有经过filter()(例如,输出中没有Filtering 5: false),对吧?还是我错过了什么?
  • @anlr 因为limit() 是短路操作
  • 不完全明白短路是什么意思,需要在线阅读更多。但是一个快速的问题,这是否意味着它会在任意时间后终止管道执行?
  • @anir 是的。短路的一个例子是&& 运算符。在(a == 1 && b == 1) 中,如果左侧条件为假,则不评估右侧条件。
  • @anir,Java Stream API 在“pull-way”中工作,而不是“push-way”。这意味着它首先评估最后一个操作,并且第一个操作在链中最后。而且因为这是“拉式”,所以没有任何方法可以“拉”出比“限制”阶段定义的更多的元素。
猜你喜欢
  • 1970-01-01
  • 2014-06-25
  • 2013-06-03
  • 2018-05-19
  • 1970-01-01
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-31
相关资源
最近更新 更多