Reputation: 43867
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
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
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
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
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