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.