I am using .peek() in my stream but it is frowned upon, sadly I can't find a solution.
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. 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()
:
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?I'm looking for a correct solution, not a working solution, all of those codes are already working.
This method exists mainly to support debugging, where you want to see the elements as they flow past a certain point in a pipeline. Since Java 9, if the number of elements is known in advance and unchanged in the stream, the . peek () statement will not be executed due to performance optimization.
(1): using stream. foreach, you can also change the internal property value of each item in the list, etc., but you need to perform "secondary flow processing" to get the smallest item in the list (filter according to age). (2): stream. peek can get the smallest item directly compared with stream.
Introduced in Java 8, the Stream API is used to process collections of objects. A stream is a sequence of objects that supports various methods which can be pipelined to produce the desired result. A stream is not a data structure instead it takes input from the Collections, Arrays or I/O channels.
peek() method is very useful for debugging and understating the stream-related code in Java.
the documentation of Stream#peek
has mentioned as below, and mainly is not absolutely:
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:
the most useful thing you can do with
peek
is to find out whether a stream element has been processed.
and some side-effects he has also pointed it out in his answer, the peek
operation depends on which terminal operation was invoked. so when using peek
internally you should be carefully.
so the correctly way is just using for-each
loop, since Stream#collect
doesn't support short-circuiting operation.
the optional way is using peek
because you can control the stream by yourself. and you need to remove the synchornized
block, it is unnecessary here.
return IntStream.range(0, size).peek(foo::add).allMatch(__ -> Foo.isLegal(foo));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With