Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to iterate x times using Java 8 stream? [duplicate]

I have an old style for loop to do some load tests:

For (int i = 0 ; i < 1000 ; ++i) {
  if (i+1 % 100 == 0) {
    System.out.println("Test number "+i+" started.");
  }
  // The test itself...
}

How can I use new Java 8 stream API to be able to do this without the for?

Also, the use of the stream would make it easy to switch to parallel stream. How to switch to parallel stream?

* I'd like to keep the reference to i.

like image 857
AlikElzin-kilaka Avatar asked Nov 13 '16 12:11

AlikElzin-kilaka


People also ask

How do I find duplicate values in Java 8?

In Java 8 Stream, filter with Set. Add() is the fastest algorithm to find duplicate elements, because it loops only one time. Set<T> items = new HashSet<>(); return list.

How do I reuse a stream in Java 8?

As others have noted the stream object itself cannot be reused. But one way to get the effect of reusing a stream is to extract the stream creation code to a function. You can do this by creating a method or a function object which contains the stream creation code. You can then use it multiple times.

Is Java 8 stream faster than for loop?

Yes, streams are sometimes slower than loops, but they can also be equally fast; it depends on the circumstances. The point to take home is that sequential streams are no faster than loops.

Can Java stream be reused and visited many times?

So the simple answer is : NO, we cannot reuse the streams or traverse the streams multiple times. Any attempt to do so will result in error : Stream has already been operated on or closed.


1 Answers

IntStream.range(0, 1000)
         /* .parallel() */
         .filter(i -> i+1 % 100 == 0)
         .peek(i -> System.out.println("Test number " + i + " started."))
         /* other operations on the stream including a terminal one */;

If the test is running on each iteration regardless of the condition (take the filter out):

IntStream.range(0, 1000)
         .peek(i -> {
             if (i + 1 % 100 == 0) {
                 System.out.println("Test number " + i + " started.");
             }
         }).forEach(i -> {/* the test */});

Another approach (if you want to iterate over an index with a predefined step, as @Tunaki mentioned) is:

IntStream.iterate(0, i -> i + 100)
         .limit(1000 / 100)
         .forEach(i -> { /* the test */ });

There is an awesome overloaded method Stream.iterate(seed, condition, unaryOperator) in JDK 9 which perfectly fits your situation and is designed to make a stream finite and might replace a plain for:

Stream<Integer> stream = Stream.iterate(0, i -> i < 1000, i -> i + 100);
like image 113
Andrew Tobilko Avatar answered Sep 28 '22 02:09

Andrew Tobilko