Reputation: 1725
I have a use case like following:
SET is a Set of Integer with size N
for i in SET (I mean only iterate the Set of size N at start point):
if i + 7 not in SET:
SET.add(i + 7)
return SET
How to implement this using Java HashSet except using an auxiliary list/set to store the element which needs to be inserted?
Upvotes: 2
Views: 2054
Reputation: 4054
It is impossible to add something to the Set
instance while iterating over its contents; when using the foreach
loop (for( var e : set )
notation), no modification is allowed, while when using an explicit iterator (for( var i = set.iterator(); i.hasNext(); ) …
notation), you can call i.remove()
to get rid of the current element. But adding new elements does still not work in this case.
This behaviour is shared by all Java Collection classes, although List
knows a special iterator class, ListIterator
, that also allows adding entries (notation for( var i = list.listIterator(); i.hasNext(); ) …
) by calling i.add()
– thanks to @lucasvw for reminding me on that.
Upvotes: 4
Reputation: 13225
If you do not want to make a copy yourself, Java can do that for you: https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CopyOnWriteArraySet.html. It will not be faster or anything magical, but you can iterate "the original" and modify at the same time.
However if you want something efficient, that is presumably to create another Set
with the new elements, and addAll()
them at the end. Depending on the size of the set it may be faster to skip the containment-check, and leave it for the merging.
BitSet
and its or()
operation may be also something to look at if your numbers are nonnegative and are of low magnitude.
Upvotes: 1
Reputation: 312259
@lucasvw eluded to the underlying issue here - you need to somehow differentiate between the original values and the values you've added, otherwise, the loop will run indefinitely (or, at least, until the values overflow enough so they start repeating themselves).
The best way to do this is to indeed have an auxiliary set to hold all the values you want to add:
Set<Integer> aux = original.stream().map(i -> i + 7).collect(Collectors.toSet());
original.addAll(aux);
Upvotes: 2