我在使用流中的.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();
)};
我的问题与这个问题非常相似,不同之处在于我每次都在检查,所以那些解决方案都不起作用。
所以我的问题是:
.peek()
只能用于调试吗?还是我可以用它来实现我的需求?- 有更好的解决方案吗?
- 我应该使用第二种解决方案吗?
我正在寻找正确的解决方案,而不仅仅是一个可行的解决方案,所有那些代码都已经可行。
synchronized
不会对你有太大的帮助 - 它只会保证一次只能将一个元素放入foo
; 但它不会保证 哪个 元素被放到foo
中,因为在并行流情况下不存在处理顺序。 - Eugener
?为什么您要在其上进行同步?您的流代码与循环不匹配。您正在对int
值进行流处理,因此您需要一个静态方法Foo.isLegal(int)
来使第一个片段被编译器接受。在最后一个片段中,您正在使用方法引用Foo :: isLegal
,而在此处不允许使用方法引用。显然,您从未尝试过这些替代方案。 - HolgerFoo::isLegal
的逻辑是什么?看着你的“逻辑等价”示例,可能有更好的逻辑解决方案来解决你的问题。 - SubOptimal