Ashish
Ashish

Reputation: 1917

Is Java 8 filters on Stream of large list more time consuming than for loop?

I was replacing one of my legacy code from simple for loop over a list to Java 8 stream and filters.

I have the for loop like below:

List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
for(int i: numbers) {
    if((i > 4) && (i % 2 == 0)) {
         System.out.println("First even number in list more than 4 : " +  numbers.get(i))
         break;
    }
}

Here I have 6 iterations of the loop. When 6 is obtained, I print it.

Now, I am replacing it with below:

numbers.stream()
       .filter(e -> e > 4)
       .filter(e -> e % 2 == 0)
       .findFirst()

I am confused, if we are applying filter twice on the list, then is the time complexity more than the for loop case or is there something I am missing?

Upvotes: 1

Views: 1219

Answers (1)

MikeFHay
MikeFHay

Reputation: 9003

The answer to your question is no. A stream with multiple filter, map, or other intermediate operations is not necessarily slower than an equivalent for loop.

The reason for this is that all intermediate Stream operations are lazy, meaning that they are not actually applied individually at the time the filter method is called, but are instead all evaluated at once during the terminal operation (findFirst() in this case). From the documentation:

Stream operations are divided into intermediate and terminal operations, and are combined to form stream pipelines. A stream pipeline consists of a source (such as a Collection, an array, a generator function, or an I/O channel); followed by zero or more intermediate operations such as Stream.filter or Stream.map; and a terminal operation such as Stream.forEach or Stream.reduce.

Intermediate operations return a new stream. They are always lazy; executing an intermediate operation such as filter() does not actually perform any filtering, but instead creates a new stream that, when traversed, contains the elements of the initial stream that match the given predicate. Traversal of the pipeline source does not begin until the terminal operation of the pipeline is executed.

In practice, since your two pieces of code do not compile to exactly the same bytecode, there will likely be some minor performance difference between them, but logically they do very similar things and will perform very similarly.

Upvotes: 3

Related Questions