13

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.

AlikElzin-kilaka
  • 34,335
  • 35
  • 194
  • 277
  • 1
    what does the phrase *"I'd like to keep the reference to i."* mean if `i` is a primitive? – Andrew Tobilko Nov 13 '16 at 12:31
  • and is the test running regardless of the condition? – Andrew Tobilko Nov 13 '16 at 12:35
  • Try this `IntStream.range(0, 1000).filter(i->((i+1)%100 ==0)).forEach(i->System.out.printf("Test number %d started.%n", i));` – Naruto Biju Mode Nov 13 '16 at 12:38
  • 3
    Judging by the current code, the test is ran for all `i` values, not every 100. Is this the intention? Do you want to iterate over an index with a predefined step, like shown here http://stackoverflow.com/questions/32586604/is-it-possible-to-use-streams-intrange-function? – Tunaki Nov 13 '16 at 12:45
  • I just want to notify about the progress each 100 handled elements. I should have done it time wise, but I think it's too late. The answers took it as part of the question. – AlikElzin-kilaka Nov 13 '16 at 14:48

2 Answers2

25
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);
Andrew Tobilko
  • 48,120
  • 14
  • 91
  • 142
2

You can use IntStream as shown below and explained in the comments:

(1) Iterate IntStream range from 1 to 1000

(2) Convert to parallel stream

(3) Apply Predicate condition to allow integers with (i+1)%100 == 0

(4) Now convert the integer to a string "Test number "+i+" started."

(5) Output to console

IntStream.range(1, 1000). //iterates 1 to 1000
   parallel().//converts to parallel stream
   filter( i -> ((i+1)%100 == 0)). //filters numbers & allows like 99, 199, etc..)
   mapToObj((int i) -> "Test number "+i+" started.").//maps integer to String
   forEach(System.out::println);//prints to the console
Vasu
  • 21,832
  • 11
  • 51
  • 67