0

I have a code that iterates on ArrayMap keys, and I got an Array Index Out Of Bounds Exception from unknown reason

From Crashalytics:

Fatal Exception: java.lang.ArrayIndexOutOfBoundsException
length=56; index=56
android.util.ArrayMap$1.colGetEntry (ArrayMap.java:763)
android.util.MapCollections$ArrayIterator.next (MapCollections.java:55)

The code looks like that:

private ArrayMap<String,RequestData> handlers = new ArrayMap<>();

public void removeAllHandlers() {
    synchronized (handlers) {
        for (String s : handlers.keySet()) {
            handlers.remove(s);
        }
    }
}

the Exception happened at this line: for (String s : handlers.keySet())

Any clue what am I doing wrong?

2
  • indices are 0 based in Java, the maximal index is 55, you are trying to retrieve the 57th element of an array with 56 elements. removing elements from a Map while iterating over the same map is asking for trouble. Commented Aug 14, 2018 at 8:27
  • How about handlers.clear()? Commented Aug 14, 2018 at 8:29

4 Answers 4

2

You cannot remove from a Map or a List while iterating. Use the internal clear method of the Map/List. For instance, handlers.clear();

Code:

private ArrayMap<String,RequestData> handlers = new ArrayMap<>();

public void removeAllHandlers() {
        synchronized (handlers) {
                handlers.clear();
        }
    }
Sign up to request clarification or add additional context in comments.

Comments

0

Try this

private ArrayMap<String,RequestData> handlers = new ArrayMap<>();

public void removeAllHandlers() {
    synchronized (handlers) {
        ArrayMap<String,RequestData> tempHandlers = handlers;
        for (String s : tempHandlers.keySet()) {
            handlers.remove(s);
        }
    }
}

Comments

0

You are modifying the ArrayMap that your are iterating over. This is an anti-pattern in Java and will cause error. I recommend you using another ArrayMap for your modifications.

Comments

0

Just as others mentioned, you cannot remove(Object o) in a for loop, you have to do that removal using Iterator as

public void removeAllHandlers() {
    synchronized (handlers) {
            Iterator<String> keyIterator = handlers.keySet().iterator();
            while (keyIterator.hasNext()) {
                 RequestData requestData = handlers.get(keyIterator.next());
                 if(iDontWant(requestData)) {
                     keyIterator.remove();
                 }
            }
    }
}

Comments

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.