0

I have a pizza code that iterates through a list of objects and checks whether they are colliding or not. If one is collided with, it is removed from the ArrayList.

for (int i = 0; i < arrayList.size(); i++) {
    Object c = arrayList.get(i);
    if (Rect.intersects(foo.getRect(), c.getRect())) { //Android function, checks if the two rectangles are inside each other.
        foo.setPosY(c.getPosY() + 11); // Always works.
        foo.setVelY(bird.getVelY() * -1); // Always works.
        arrayList.remove(i); // Occasionally fails under special circumcisions.
    }
}

When opening the app fresh for the first time this works fine. However, if I exit with the back button and then quickly reopen the app, it will all work except occasionally, removing the object from the ArrayList wont happen.

If I close the app and then remove it from the recent apps list, it works. If I exit with the home key, or the back button and then immediately reopen, it sometimes fails to remove the object. I don't understand why this happens, as everything else still works. The two lines of code just before it function just fine. I just don't get it.

6
  • 2
    How can this code work? c is declared as an Object and Object has no .get*() methods... Or is this something else than java.lang.Object? Commented Feb 21, 2014 at 9:53
  • 3
    Firstly, you're always skipping an element after you remove one. Either work from back to front, or decrement i after a remove operation, or use an iterator. Commented Feb 21, 2014 at 9:53
  • @fge, Sorry. I meant for that to imply a custom class of mine. It's just a foo object that has a rect that you can get. Commented Feb 21, 2014 at 9:55
  • @JonSkeet: does remove() method put null at that position or entirely remove it from list?? Commented Feb 21, 2014 at 9:55
  • 1
    @RipalTamboli: It removes it completely from the list, and later elements are moved up. Commented Feb 21, 2014 at 9:55

1 Answer 1

5

I suspect the problem is that you're skipping an element after one call to remove, because you're incrementing i and everything in the list is moving up one element. (It's not really clear what the symptoms are at the moment. If this turns out not to be the problem, it's still a problem.)

So if you call remove(2), the next element you want to look at now has index 2.

Common ways of fixing this:

  • Work backwards:

    for (int i = arrayList.size() - 1; i >= 0; i--)
    
  • Use an iterator instead:

    for (Iterator<Foo> iterator = arrayList.iterator(); iterator.hasNext(); ) {
        Foo c = iterator.next();
        if (...) {
            iterator.remove();
        }
    }
    
Sign up to request clarification or add additional context in comments.

6 Comments

Wow, thanks. I can't believe how long I've overlooked that. I've fixed that issue and tested it. Unfortunately the problem still persists. I am thankful for you pointing that out though. I will be more mindful in the future.
@user3321627: If the problem still persists, you should edit your question to give more diagnostic information. ArrayList.remove() definitely do work, so I suggest you log the contents before and after the remove() call...
@Skeet, yes, it does 100% work as long as it's not in the recent list. I cannot get it to show this behavior on a fresh start. I've tried 100+ times. It will only do it after it's been ran, and it will do it often at the point, but not every time. I've tried using debug mode, and it will show the same behavior but only while actually running. It will not do it while I'm stepping through.
@Jimicrackcorn: Then add logging anyway, and look at the log after it's failed.
thank you. I will try to figure out how to do that.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.