Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transforming a while loop to a stream in Java 8

As an exercise I'm converting some old code to functional streams. I don't know much about streams. It seems like it should be simple to convert this code, but I haven't had much luck. The method starts at a given integer, passes it to isPrime, which returns true if it's prime. and then hands off the new(next) prime number to be printed. If isPrime is false i is incremented and we check the next integer.

private static int nextPrime(final int number) {
    int i = number + 1;

    while (!isPrime(i)) {
        i++;
    }

    return i;
}
like image 692
scott parent Avatar asked Mar 02 '18 19:03

scott parent


People also ask

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.

Does Java 8 support streams?

Java 8 offers the possibility to create streams out of three primitive types: int, long and double. As Stream<T> is a generic interface, and there is no way to use primitives as a type parameter with generics, three new special interfaces were created: IntStream, LongStream, DoubleStream.

Is Java stream better than for loop?

If you have a small list, loops perform better. If you have a huge list, a parallel stream will perform better. Purely thinking in terms of performance, you shouldn't use a for-each loop with an ArrayList, as it creates an extra Iterator instance that you don't need (for LinkedList it's a different matter).


1 Answers

I see no reason to use a Stream for this other than to take advantage of parallelism (if the primes happen to be very far apart, but this won't be true within int bounds, so there's essentially no benefit).

You can iterate over an IntStream of ascending integers (starting from number + 1) and filter only the prime numbers. When one is inevitably found, you can return the first.

private static int nextPrime(final int number) {
    return IntStream.iterate(number + 1, i -> i + 1)
                    .filter(Test::isPrime)
                    .findFirst()
                    .getAsInt();
}

Note: The class that I used to test this is called Test, as seen by the method reference. You should change that to your class name.

like image 54
Jacob G. Avatar answered Oct 19 '22 17:10

Jacob G.