Java - Error when removing from an ArrayList more than once. (IllegalStateException)

14,446

Solution 1

Your iterator wasn't initialized properly (next() was not called). I suggest to write this code like this:

Iterator<ConfigItem> it = configItems.iterator();
while(it.hasNext()){
    ConfigItem c = it.next();
    if (c.ITEM.equals(item))
    {
        it.remove();
        break;
    }
}

Solution 2

You can call Iterator.remove() only after Iterator.next(). Try this:

Iterator<ConfigItem> i = configItems.iterator();
while(i.hasNext()) {
    ConfigItem next = i.next();
    if (next.equals(item))
    {
        i.remove();
        break;
    }
Share:
14,446
AppleDash
Author by

AppleDash

I'm a pony who likes to code. That's about it.

Updated on June 04, 2022

Comments

  • AppleDash
    AppleDash almost 2 years

    I've been googling around for quite a bit, and can't seem to find a solution. What have I done wrong here? My problem is in the title. Here is the exception I get:

    java.lang.IllegalStateException
    at java.util.ArrayList$Itr.remove(Unknown Source)
    at me.herp.derp.client.Config.updateItem(Config.java:24)
    at me.herp.derp.client.Commands.parseCommand(Commands.java:23)
    at me.herp.derp.client.ChatCommands.handleChatcommand(ChatCommands.java:29)
    at net.minecraft.src.EntityClientPlayerMP.sendChatMessage(EntityClientPlayerMP.java:171)
    at net.minecraft.src.GuiChat.keyTyped(GuiChat.java:104)
    at net.minecraft.src.GuiScreen.handleKeyboardInput(GuiScreen.java:227)
    at net.minecraft.src.GuiScreen.handleInput(GuiScreen.java:176)
    at net.minecraft.client.Minecraft.runTick(Minecraft.java:1494)
    at net.minecraft.client.Minecraft.runGameLoop(Minecraft.java:843)
    at net.minecraft.client.Minecraft.run(Minecraft.java:768)
    at java.lang.Thread.run(Unknown Source)
    

    And here is my code:

    public static void updateItem(String item, String value)
    {
        if (!hasValue(item))
        {
            addItem(item, value);
            return;
        }
        for (ConfigItem c : configItems)
        {
            if (c.ITEM.equals(item))
            {
                configItems.iterator().remove();
                break;
            }
        }
        ConfigFile.saveConfig();
    }
    
    • Rohit Jain
      Rohit Jain over 11 years
      Didn't you find on google, that you should only use iterator to iterate over your list, if you want to modify it?
    • Abubakkar
      Abubakkar over 11 years
      @RohitJain yuo are right, post it as an answer with some explanation about it, I am sure it will help at least OP and me
    • AppleDash
      AppleDash over 11 years
      @RohitJain But I am modifying it...
    • Rohit Jain
      Rohit Jain over 11 years
      @Abu.. and OP. See this post - stackoverflow.com/questions/223918/…. It best explains it.
    • Abubakkar
      Abubakkar over 11 years
      @RohitJain thanks but the link is not proper please edit it.
    • Rohit Jain
      Rohit Jain over 11 years
      @Abu.. It's working for me. Please try it again.
    • Rohit Jain
      Rohit Jain over 11 years
      @Abu.. Or you can go to the wiki section of Java. There in the bottom most part, you have the link to this post.
  • remigio
    remigio over 11 years
    @bellum Although the code you show works, your answer isn't correct, because there is no relation between the hidden iterator used in the for loop and the iterator used in the if block. The remove method fails because it's called on an iterator not yet started, as @Evgeniy correctly points out. The same result could be obtained calling configItems.remove(c) inside the if.
  • Swapnil Sawant
    Swapnil Sawant over 8 years
    I had complex requirement. There were nested iterator. On a condition of inner iterator have to remove object from outer iterator. the break statement from your answer helped me out. Thanks for sharing