stonar96
stonar96

Reputation: 1461

Java Set Iterator#remove() or Set#clear() afterwards?

I have for example a Set<Object> objects or more specific objects = new HashSet<>().

Now I want to iterate over the set, invoke something for each element and then remove the element from the set.

Iterator<Object> iterator = objects.iterator();

while (iterator.hasNext()) {
    Object object = iterator.next();
    System.out.println(String.valueOf(object));
    iterator.remove();
}

Is it better (faster, more readable, more preferable) to use Set#clear() afterwards instead of using Iterator#remove() inside the loop?

for (Object object : objects) {
    System.out.println(String.valueOf(object));
}

objects.clear();

Upvotes: 2

Views: 648

Answers (1)

John Bollinger
John Bollinger

Reputation: 180113

Is it better (faster, more readable, more preferable) to use Set#clear() afterwards instead of using Iterator#remove() inside the loop?

There is no reason to think that the clear() method would be any slower than removing all the elements individually via the iterator. Even if it were implemented naively, you would expect to at least save on method invocation overhead. In practice, clear() has an opportunity to be much more efficient.

But looking at it from a performance perspective is probably premature. This is unlikely to be a bottleneck in your code, so making it faster is unlikely to produce a noticeable difference. But you won't know for sure unless you test the performance via a profiler.

Usually it is best to focus first on functionality, and second on clarity and simplicity. Consider issues such as what should happen if you abort in the middle of iterating over the set: is it right for some, but not all, elements to then have been removed? Or do you need the original size of the set for anything? Etc. Perform performance optimizations only when and where measurements demonstrate a potential for improvement.

If indeed both approaches are equally good from a functionality perspective, then allow me to observe that using clear() affords an even better simplification than just removing the Iterator.remove() invocation from the loop: you can rewrite the loop as an enhanced for loop or a stream pipeline.

The question already demonstrates the enhanced for alternative; here's the streams one:

objects.stream()
       .forEach(o -> System.out.println(String.valuef(o)));
objects.clear();

Both of these have considerable clarity advantages over your original Iterator-based code.

Upvotes: 4

Related Questions