Pace
Pace

Reputation: 43867

What is the fastest way to iterate on a stream in Java 8?

If I have a collection and I want to iterate over a filtered stream then I could do either of the following (and many more obtuse options):

for(item in collection.stream().filter(...).collect(Collectors.toList()))
for(item in collection.stream().filter(...).collect(Collectors.toSet()))

Which is faster? A list or a set? Is there some way to collect to simply an Iterable or some other type I can iterate on?

Upvotes: 5

Views: 6147

Answers (4)

Rinke
Rinke

Reputation: 21

If performance is what you are aiming at, don't use streams at all. Streams are nice, but they are almost always slower than plain old java iteration.

What is then the fastest depends a bit on the situation. If it is pure for iterating, then ArrayList outperforms HashSet. The fastest way to iterate over an ArrayList is not the for-each loop, but the plain old i-iteration:

int size = list.size();
for (int i = 0; i < size; i++) {
    ...list.get(i)...
}

Make sure that you read the size outside of the loop to a local variable, otherwise you get many unnecessairy calls to list.size().

If you need filtering the original list, just adding some if inside this loop is almost always faster than using streams with filter.

Upvotes: 0

Karol Kr&#243;l
Karol Kr&#243;l

Reputation: 3530

If you don't care about elements order use parallelStream:

collection.parallelStream().filter(...).forEach(...)

This way you iterate through the collection using more threads.

To mesure which stream or parallelStream procesing is faster for a specific case review @Brian Goetz answer for the related problem

Upvotes: 3

Radiodef
Radiodef

Reputation: 37855

Is there some way to collect to simply an Iterable or some other type I can iterate on?

If for some reason you did want to use a Stream as the target of a for-each loop, you don't have to collect it:

for (Item item : (Iterable<Item>)
        coll.stream().filter(...)::iterator) {
}

or:

Iterable<Item> iter = coll.stream().filter(...)::iterator;
for (Item item : iter) {
}

This works because Iterable is a functional interface, even though it is not annotated as such.

It's just an interesting thing to know about, though. forEach as Eran has suggested is probably the 'right' way to go about things in general. The java.util.stream package description describes iterator as an "escape hatch".

Upvotes: 2

Eran
Eran

Reputation: 393936

If you only want to iterate over the elements of the Stream, there's no need to collect it into a Collection, just use forEach :

collection.stream()
          .filter(...)
          .forEach (item -> {
                            // do something with item
                            }
                   );

Upvotes: 10

Related Questions