• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 422
  • Last Modified:

Why is the following code resulting in a java.lang.IndexOutOfBoundsException error?

Why is the following code resulting in a java.lang.IndexOutOfBoundsException error?

private void updateContent() throws InvalidDataException {

    // Here you "move" each of your entities, and then instruct them to "update" themselves.
    int index = 0;
    while(!(entities.isEmpty())){
        if(index == entities.size()){
            index = 0;
        }
        Entity item = entities.get(index);
        if (item.isDestroyed()){
            ViewManager.getInstance().removeItem(entities.get(index).getIdentifier());
            entities.remove(index);
            //INSTRUCT THE ENTITY TO PERFORM IT'S DESTROYED BEHAVIOR item.Destroyed()                    
        } else {
            item.update(1);
            ConsoleItem ci = new ConsoleItemImpl(item.getIdentifier(), item.getLocation(), ColorStringConverter.getInstance().StringToColor(item.getSide()), item.getAngle(), item.getShape(), item.toString(), item.isDestroyed(), item.isDamaged());
            ViewManager.getInstance().updateItem(ci);                    
        }
        item.updateActivity();
        item.update(1);
        index++;
    }
    // updateInfo call
    ViewManager.getInstance().updateInfo(summary());
}

Open in new window


I believe it may have started when I go the removal part of the code working? If I can remove while looping through an ArrayList then how am I supposed to remove without breaking out of the loop?
0
Eindoofus
Asked:
Eindoofus
  • 3
  • 2
  • 2
  • +1
1 Solution
 
for_yanCommented:
Put exception.printStackTrace() - you'll know the exact line where it throws this execption
0
 
EindoofusAuthor Commented:
The following code fixes is and I don't see an Exception outputted. Why is that?

private void updateContent() throws InvalidDataException {
try{
            // Here you "move" each of your entities, and then instruct them to "update" themselves.
            int index = 0;
            while(!(entities.isEmpty())){
                if(index == entities.size()){
                    index = 0;
                }
                Entity item = entities.get(index);
                if (item.isDestroyed()){
                    ViewManager.getInstance().removeItem(entities.get(index).getIdentifier());
                    entities.remove(index);
                    //INSTRUCT THE ENTITY TO PERFORM IT'S DESTROYED BEHAVIOR item.Destroyed()                    
                } else {
                    item.update(1);
                    ConsoleItem ci = new ConsoleItemImpl(item.getIdentifier(), item.getLocation(), ColorStringConverter.getInstance().StringToColor(item.getSide()), item.getAngle(), item.getShape(), item.toString(), item.isDestroyed(), item.isDamaged());
                    ViewManager.getInstance().updateItem(ci);                    
                }
                item.updateActivity();
                item.update(1);
                index++;
            }
            // updateInfo call
            ViewManager.getInstance().updateInfo(summary());
} catch(Exception e) {
    e.printStackTrace();    
}

Open in new window

0
 
Hugh McCurdyCommented:
It you think you know where it's throwing the exception, then print information about that line before you get there.  Consider if it's the removeItem() line.

System.out.println ( getIdentifier() );
System.out.println ( entities.get(index).getIdentifier());

and so forth.  You are looking for something that doesn't make any sense.
0
Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

 
stachenovCommented:
Suppose index is entities.size() - 1:

1. You check whether is index == entities.size(), and it's false, so you go on.

2. You call entities.get(index). Ok.

3. You call entities.remove(index) if the item is "destroyed". Ok, but now index == entities.size() since size is reduced by 1.

4. You do index++ so now it's entities.size() + 1.

On the next iteration, the "index == entities.size()" fail so you try to get entities.size() + 1 element, hence the index out of bounds exception.

I think you should only increase the index if you don't remove the current item, like this:
 
private void updateContent() throws InvalidDataException {

    // Here you "move" each of your entities, and then instruct them to "update" themselves.
    int index = 0;
    while(!(entities.isEmpty())){
        if(index == entities.size()){
            index = 0;
        }
        Entity item = entities.get(index);
        if (item.isDestroyed()){
            ViewManager.getInstance().removeItem(entities.get(index).getIdentifier());
            entities.remove(index);
            //INSTRUCT THE ENTITY TO PERFORM IT'S DESTROYED BEHAVIOR item.Destroyed()                    
        } else {
            item.update(1);
            ConsoleItem ci = new ConsoleItemImpl(item.getIdentifier(), item.getLocation(), ColorStringConverter.getInstance().StringToColor(item.getSide()), item.getAngle(), item.getShape(), item.toString(), item.isDestroyed(), item.isDamaged());
            ViewManager.getInstance().updateItem(ci);                    
            index++; // added this
        }
        item.updateActivity();
        item.update(1);
        // index++; // removed this
    }
    // updateInfo call
    ViewManager.getInstance().updateInfo(summary());
}

Open in new window

0
 
for_yanCommented:
>The following code fixes is and I don't see an Exception outputted.

So you mean that you fixed it?
0
 
stachenovCommented:
I don't think it's fixed in that example. It looks like exception happens only if the last element in the list is "destroyed", which could be quite random.
0
 
EindoofusAuthor Commented:
@stachenov, is there any way that I can fix this?
0
 
stachenovCommented:
I have already posted possible fix above. It basically amounts to that you shouldn't increase the index if you remove an item from the list (since index is already points to the next element after removal).

Of course, it only fixes a possible bug in the visible code. It is still possible that there are other exceptions deep down the stack in some of the functions called. You'll need a stack trace to fix that if it happens.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 3
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now