我在我的流中使用 .peek() 但它不受欢迎,遗憾的是我找不到解决方案。
简化版:
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());
}
我需要做的是遍历 IntStream 并检查每次插入后 foo 数据结构是否合法。 这在逻辑上等同于:
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;
}
但是它更复杂,我正在尝试使用流来简化和学习。
一种不使用 .peek()
的方法是这样的:它确实有效 - 但我只是将问题“移动”到 .allMatch()
:
return IntStream.range(0, size).
.allMatch(i -> {
synchronized(r){foo.add(i)};
foo.isLegal();
)};
我的问题与this question 非常相似,不同之处在于我每次都在检查,所以解决方案不起作用。
所以我的问题是:
.peek()
真的只是为了调试还是我可以以这种方式使用它?- 有没有更好的解决方案?
- 我应该使用第二种解决方案吗?
我正在寻找一个正确的解决方案,而不是一个有效的解决方案,所有这些代码都已经在工作了。
最佳答案
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绝对回答了这个问题:
the most useful thing you can do with
peek
is to find out whether a stream element has been processed.
他还在回答中指出了一些副作用,peek
操作取决于调用了哪个终端操作。所以在内部使用 peek
时你应该小心。
所以正确的方法是使用for-each
循环,因为Stream#collect
不支持short-circuiting operation .
可选的方法是使用peek
,因为您可以自己控制流。并且您需要删除 synchornized
block ,这里没有必要。
return IntStream.range(0, size).peek(foo::add).allMatch(__ -> Foo.isLegal(foo));
关于java - .peek() 在 java 8 流中的使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44759090/