[英]The use of .peek() in java 8 streams
I am using .peek() in my stream but it is frowned upon, sadly I can't find a solution. 我在我的流中使用了.peek(),但它很不满意,遗憾的是我无法找到解决方案。
Simplified version: 简化版:
static boolean fooAddTester(int size) {
Foo foo = new foo(); //data structure
return IntStream.range(0, size).
.peek(i -> synchronized(r){foo.add(i)})
.allMatch(e -> foo.isLegal());
}
what I need to do is to iterate over the IntStream and to check after every insert if the foo data structure is legal. 我需要做的是迭代IntStream并在每次插入后检查foo数据结构是否合法。 This is logically equivalent to: 这在逻辑上等同于:
static boolean fooAddTester(int size) {
Foo foo = new foo(); //data structure
for(int i=0; i<size; i++){
foo.add(i);
if(!foo.isLegal())
return false;
return true;
}
However it is more complex and I'm trying to use streams to simplify and learn. 然而,它更复杂,我正在尝试使用流来简化和学习。
A way to do the same without using .peek()
is this: which does work - but I'm just "moving" the problem to .allMatch()
: 不使用.peek()
就是这样:它确实有效 - 但我只是将问题“移动”到.allMatch()
:
return IntStream.range(0, size).
.allMatch(i -> {
synchronized(r){foo.add(i)};
foo.isLegal();
)};
My problem is very similar to this question , the diffrence is that I am checking every time so the solutions aren't working. 我的问题与这个问题非常相似,不同之处在于我每次都在检查,因此解决方案无效。
So my questions are: 所以我的问题是:
.peek()
really only to debugging or can I use it in this manner? .peek()
真的只是为了调试还是以这种方式使用它? I'm looking for a correct solution, not a working solution, all of those codes are already working. 我正在寻找一个正确的解决方案,而不是一个有效的解决方案,所有这些代码已经在运行。
the documentation of Stream#peek
has mentioned as below, and mainly is not absolutely : Stream#peek
的文档如下所述, 主要不是绝对的 :
This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline 此方法主要用于支持调试,您希望在元素流经管道中的某个点时查看这些元素
@Holger has answered this question absolutely: @Holger绝对回答了这个问题:
the most useful thing you can do with
peek
is to find out whether a stream element has been processed. 你可以用peek
做的最有用的事情是找出是否已经处理了一个流元素。
and some side-effects he has also pointed it out in his answer, the peek
operation depends on which terminal operation was invoked. 他在答案中也指出了一些副作用, peek
操作取决于调用哪个终端操作。 so when using peek
internally you should be carefully. 所以在内部使用peek
你应该小心。
so the correctly way is just using for-each
loop, since Stream#collect
doesn't support short-circuiting operation . 所以正确的方法就是使用for-each
循环,因为Stream#collect
不支持短路操作 。
the optional way is using peek
because you can control the stream by yourself. 可选的方法是使用peek
因为你可以自己控制流。 and you need to remove the synchornized
block, it is unnecessary here. 你需要删除synchornized
块,这里没有必要。
return IntStream.range(0, size).peek(foo::add).allMatch(__ -> Foo.isLegal(foo));
I can think of only a single way to do it if you really want to use other stream operations before your logic, but I'm not really a big fan of it... 如果你真的想在你的逻辑之前使用其他流操作,我只能想到一个单一的方法,但我不是真的很喜欢它...
boolean result = true;
try {
IntStream.range(0, 10)
.forEachOrdered(x -> {
foo.add(x);
if (!Foo.isLegal(foo)) {
throw new RuntimeException("just because");
}
});
} catch (RuntimeException re) {
result = false;
}
System.out.println(result);
Obviously you need to replace RuntimeException
with some kind of your exception. 显然,您需要使用某种异常替换RuntimeException
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.