views:

87

answers:

3

Say, I have a collection of some geolocations (in format Country > Region [ > Town [ > District]]) and I want to remove locations that overlap each other (for example, Europe > Germany overlaps Europe > Germany > Dresden and Europe > Germany > Hamburg, so the last two must be removed). I see that I need two instances of iterators to make something like this:

final Iterator<Location> outerIterator = locations.newIterator();
while (outerIterator.hasNext()) {
    final Location outer = outerIterator.next();
    final Iterator<Location> innerIterator = locations.newIterator();
    while (innerIterator.hasNext()) {            
        final Location inner = innerIterator.next();
        if (!inner.equals(outer)) {
            if (inner.overlaps(outer)) outerIterator.remove();
            else if (outer.overlaps(inner)) innerIterator.remove();
        }
    }
}

But I can't get new Iterator for the same collection. Is my algorithm incorrect or there is a way to do it right?


The final code using the advice from the answer provided by Carl Smotricz looks like this:

final Iterator<JobLocation> outerIterator = locations.iterator();
while (outerIterator.hasNext()) {
    final JobLocation outer = outerIterator.next();         
    final Iterator<JobLocation> innerIterator = locations.iterator();
    while (innerIterator.hasNext()) {
        final JobLocation inner = innerIterator.next();
        if (!inner.equals(outer) && inner.overlaps(outer)) {
            outerIterator.remove();
            break;
        }
    }
}
+3  A: 

Are you sure you meant to increment your outerIterator in the inner loop?

fd
Good catch. That looks wrong to me too.
Carl Smotricz
Yes, this is wrong of course, thanks. fixed this.
shaman.sir
+2  A: 

If you remove an object from the outer iterator, you need to break out of the inner loop immediately afterwards. I'm not sure if that will solve your problem completely, but it may get you a bit further along.

If there's still a problem, please show the error message and/or exception!

Carl Smotricz
I need to remove several elements, so I can't break here.In case of the code in example I get in frequent cases `ConcurrentModificationException`, which follow logic of collections, but not an answer for my question
shaman.sir
If you just removed the object the outer loop was pointing to, there is absolutely no sense in continuing the inner loop, which compares elements with the recently deceased `outer`. I'm advocating breaking out of the inner loop, not both. Think about it!
Carl Smotricz
Yes, you are exactly right, I'll add the final code in the question
shaman.sir
+2  A: 

I think you should opt to use a different structure for your regions, like a tree where each location has children that are contained by it. This way you can exclude all regions that overlap another after a simple look-up. No nested iterations needed.

This is easier if no location can overlap with two locations, which seems to be the case.

Nubsis