while (!set.isEmpty()) { Collection<E> toBeRemoved = new ArrayList<E>(); E first = set.iterator().next(); doSomethingWith(e); for (E e : set) { if (similar(first, e)) toBeRemoved.add(e); } set.removeAll(toBeRemoved); }
After reading your editing and understanding better, here is a solution you may like:
Collection<E> processed = new ArrayList<E>(); for (E e1 : set) { boolean similar = false; for (E e2 : processed) { if (similar(e1, e2)) similar = true; } if (!similar) { doSomethingWith(e1); processed.add(e1); } } set.clear();
Please note that, knowing nothing more about the definition of "similar," this problem is inherently quadratic. The only way to make it linear or sub-quadratic is if there was a way to smooth similar elements with the same key. In this case, you can use the second strategy above, but change the processed structure, and the part that will verify that the previous similar elements will be more effective (currently this step is linear in the number of similar groups that can be linear in common elements).
In addition, everything that is sub-quadratic will undoubtedly use more than read-only memory. If you want to have read only memory, this is the best thing you can do (this is definitely a quadratic time):
while (!set.isEmpty()) { Iterator<E> iter = set.iterator(); E first = iter.next(); doSomethingWith(first); while (iter.hasNext()) { if (similar(first, iter.next())) iter.remove(); } }
Note that using iter.remove () fixes the parallel modification problem you previously had.
Joe k
source share