Can Java 8 Streams operate on an item in a collection, and then remove it?
Solution 1:
You can do it like this:
set.removeIf(item -> {
if (!item.qualify())
return false;
item.operate();
return true;
});
If item.operate()
always returns true
you can do it very succinctly.
set.removeIf(item -> item.qualify() && item.operate());
However, I don't like these approaches as it is not immediately clear what is going on. Personally, I would continue to use a for
loop and an Iterator
for this.
for (Iterator<Item> i = set.iterator(); i.hasNext();) {
Item item = i.next();
if (item.qualify()) {
item.operate();
i.remove();
}
}
Solution 2:
In one line no, but maybe you could make use of the partitioningBy
collector:
Map<Boolean, Set<Item>> map =
set.stream()
.collect(partitioningBy(Item::qualify, toSet()));
map.get(true).forEach(i -> ((Qualifier)i).operate());
set = map.get(false);
It might be more efficient as it avoids iterating the set two times, one for filtering the stream and then one for removing corresponding elements.
Otherwise I think your approach is relatively fine.