我的问题以最简单的可表达方式:
根据JavaDoc:
Peek()
方法的存在主要是为了支持调试,您希望在元素流经管道中的某个点时看到它们。
我有一个10米的管道,在距离输入头3和7米的地方,我有两个标记[aka peek()
]用于检查/调试我的元素。
现在从输入端开始,我给出<code>1,2,3,4,5</code>的输入。
在点x = 4米处,我有一个< code>filter()来过滤所有小于等于< code>3的元素。
现在根据Java文档,我应该能够看到我在管道中的输入在距离3
和7
米处发生了什么。
距离3处的标记1的输出(. peek()
)应该是1,2,3,4,5
不应该是??距离7处的标记2的输出显然应该是4,5
。
但这实际上并没有发生,产出来自第一市场。peek())只有< code>1,2,3,第二个是< code>4,5。
我执行的代码来测试我的理论:
final List<Integer> IntList=
Stream.of(1, 2, 3, 4, 5)
.peek(it -> System.out.println("Before Filtering "+it)) // should print 1,2,3,4,5
.filter(it -> it >= 3)
.peek(it -> System.out.println("After Filtering: "+it)) //should print 4,5
.collect(Collectors.toList());
实际产量:
Before Filtering 1
Before Filtering 2
Before Filtering 3
After Filtering: 3
Before Filtering 4
After Filtering: 4
Before Filtering 5
After Filtering: 5
预期输出(开发人员在阅读JavaDoc(…存在主要是为了支持调试,您希望看到元素流经管道中的某个点…)
Before Filtering 1
Before Filtering 2
Before Filtering 3
Before Filtering 4
Before Filtering 5
After Filtering: 4
After Filtering: 5
如果 .peek()
不仅适用于在管道中的特定点进行html" target="_blank">调试,那么 def 就是模棱两可的。
对不起,我的烟斗的故事,我想这样我可以解释我想问的最好的。
安德烈·艾哈迈托夫的回答是正确的,但我想补充一点,因为这里有两个问题。一个是流管道语义的一般问题 - 这确实是你的问题所在。第二个是关于peek()
的含义和局限性。
对于主要问题——这与<code>peek()
collection.stream()
.filter(x -> x.foo() > 3)
.map(X::toBar)
.forEach(b -> System.out.println("Bar: " + b);
所有过滤发生在所有映射之前,所有打印之前。流可以自由地以它喜欢的任何顺序交错过滤、映射和打印。(聚合中有一些顺序保证。)这里的好处是,在某些具有无限流的情况下,这通常更具性能、更可并行化,并且更健壮。只要您遵循规则(即,不要依赖一个阶段在另一个阶段的副作用),您就无法区分,除非您的代码运行得更快。
peek()
使用摇摆语言的原因是,对于以下管道:
int size = collection.stream()
.map(...)
.peek(...)
.count()
我们可以在不做任何映射的情况下评估答案(因为众所周知map()是一个保持大小的操作。)总是在< code>peek()点提供元素的要求会破坏许多有用的优化。因此,如果实现可以证明它不会影响答案,它可以自由地省略整个管道的中间部分。(它可能会产生更少的副作用,但如果你这么在乎副作用,也许你不应该使用流。)
不会。流可以根据需要进行延迟计算,操作的顺序没有严格的定义,尤其是在< code>peek()操作时。这允许streams API支持非常大的流,而不会浪费大量的时间和内存,并且允许某些实现简化。特别地,在下一级被评估之前,流水线的单个级不需要被完全评估。
根据您的假设,假设以下代码会多么浪费:
IntStream.range(1, 1000000).skip(5).limit(10).forEach(System::println);
该流从100万个元素开始,以10个元素结束。如果我们完全评估每个阶段,我们的中间体将分别是100万、999995和10个元素。
作为第二个示例,以下流不能一次计算一个阶段(因为<code>IntStream.generate<code>返回无限流):
IntStream.generate(/* some supplier */).limit(10).collect(Collectors.toList());
您的管道确实通过第一个< code>peek传递每个元素,然后只通过第二个< code>peek传递一个子集。但是,管道以元素主要而不是阶段主要的顺序执行此评估:它评估管道的值为1,将其放在过滤器上,然后是2。一旦它为3评估了管道,它就传递过滤器,因此两个peek语句都执行,然后同样的情况发生在4和5上。
在Java的LinkedList中,peek和element有什么区别? 以下是OracleJava文档页面对它们的描述,但它们没有解释区别。 公共E peek() 检索但不删除此列表的头(第一个元素)。 指定者:界面中的peek Deque public E element() 检索但不删除列表的头部(第一个元素)。指定者:接口队列中的元素 区别仅仅是一个抛出异常,而另一个在列表为空的情况下返回
我有一个管道可以解析AVRO文件中的记录。 我需要将传入的记录分成500个项目的块,以便调用一个同时接受多个输入的API。 有没有办法用PythonSDK做到这一点?
问题内容: 我正在阅读有关Java流的信息,并在不断学习中发现新事物。我发现的新peek()功能之一就是功能。我偷看的几乎所有内容都说应将其用于调试Streams。 如果我有一个Stream,其中每个帐户都有一个用户名,密码字段以及一个login()和loggingIn()方法,该怎么办。 我也有 和 为什么会这么糟糕? 现在,据我所知,这确实可以实现预期的目的。它; 取得帐户清单 尝试登录每个帐
我正在阅读有关Java流的内容,并在此过程中发现了一些新的东西。我发现的一个新东西是函数。我在peek上看到的几乎所有东西都说它应该用来调试流。 如果我有一个流,其中每个帐户都有用户名、密码字段和login()和loggedIn()方法。 我也有 而且 为什么会这么糟? null 做这样的事情有什么坏处?有什么理由不让我继续吗?最后,如果不是这个解决方案,那又是什么呢? 它的原始版本使用了.fil
如果我有一个<代码>流 最明显的解决方案是使用<code>limit(originalLength-elementsToRemoveAtEnd),但这需要事先知道初始长度,这并不总是如此。 有没有一种方法可以删除长度未知的流的最后几个元素,而无需将其收集到中,计算元素并再次流式传输?
问题内容: 我的页面上有一张表格,其中应该包含某个元素。我可以通过表名(具有唯一的名称)来标识表,并且还可以轻松地标识元素。我想断言元素存在于表的row ,column 上。使用Selenium命令最干净的方法是什么? 备注: 我不想使用除表名以外的其他内容来查找它(我不希望代码中的所有内容)。 我在PHPUnit中使用Selenium。因此,我可以将PHP逻辑用于该任务,尽管我不希望任何复杂的逻