【发布时间】:2017-06-26 11:51:26
【问题描述】:
我在我的信息流中使用 .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()真的只用于调试还是我可以以这种方式使用它? - 有没有更好的解决方案?
- 我应该使用第二种解决方案吗?
我正在寻找一个正确的解决方案,而不是一个有效的解决方案,所有这些代码都已经在工作了。
【问题讨论】:
-
你要检查一个条件
after every insert;这依赖于副作用,应该避免。 -
synchronized不会对您有太大帮助 - 它会保证一次只将一个元素放入foo;但它不能保证 哪个 元素被放入 foo,因为在并行流的情况下没有处理顺序 -
“新手”的好问题
-
什么是
r?你为什么要同步它?您的流代码与循环不匹配。您正在流式传输int值,因此您需要static方法Foo.isLegal(int)以使编译器接受第一个sn-p。在最后一个 sn-p 中,您在不允许方法引用的地方使用方法引用Foo::isLegal。显然,您从未尝试过任何这些替代方案。
标签: java java-8 java-stream