1 2 3 4 Previous Next 50 Replies Latest reply: Apr 25, 2012 9:44 AM by Owen Thomas RSS

    Why the ConcurrentModificationException?

    Owen Thomas
      Hello my Java friends.

      When executing the following code:
      143        // Create the Clique's medium.
      144        this.medium.addAll(ownerIdentity.getConnection().getMediaProfileNode().flattenMediaProfile());
      145        for(MI i:candidateIdentities){
      146            Set<SourceMediaProfile>memberMedium=i.getConnection().getMediaProfileNode().flattenMediaProfile();
      147
      148            for(SourceMediaProfile ownerMediumMediaProfile:this.medium){
      149                if(memberMedium.contains(ownerMediumMediaProfile)){
      150                    continue;
      151                }
      152                this.medium.remove(ownerMediumMediaProfile);
      153            }
      ...
      165        }
      I get the following excetption:
      java.util.ConcurrentModificationException
              at java.util.HashMap$HashIterator.nextEntry(HashMap.java:810)
              at java.util.HashMap$KeyIterator.next(HashMap.java:845)
              at cliquespace.core.agentdevice.source.SourceClique.<init>(SourceClique.java:148)
      The flattenMediaProfile method has the following code:
      114    public Set<SourceMediaProfile>flattenMediaProfile() {
      115        Set<SourceMediaProfile>mps=new HashSet<SourceMediaProfile>();
      116        mps.add(this);
      117
      118        MPN mpn=null;
      119        try{
      120            mpn=(MPN)this;
      121            Collection<SourceMediaProfile<CS,?extends MediaProfileIdentifier,MPN,C,I,MI,P,OP,CL>>mpc=mpn.getParentMediaProfiles();
      122            for(SourceMediaProfile p:mpc){
      123                mps.addAll(p.flattenMediaProfile());
      124            }
      125        }catch(ClassCastException cce){/*Do nothing.*/}
      126
      127        return mps;
      128    }
      Now, I can probably create arrays to do what I'm trying to do with these collections, but I think I might be doing something wrong with the collection objects, and, rather than remaining ignorant, I would like to take this opportunity to find out what that might be.

      Your considered advice would be well received.

      Thanks,

      Owen.
        • 1. Re: Why the ConcurrentModificationException?
          931373
          It is simply because you can't remove an item from a collection or list, while in a foreach loop on that.
          instead of
            for(SourceMediaProfile ownerMediumMediaProfile:this.medium)
          use an iterator like the following :
          Iterator<SourceMediaProfile > iterator = this.medium.iterator() ;
          while (iterator.hasNext()){
          SourceMediaProfile ownerMediumMediaProfile = iterator.next() ;
          // do the remove as you wish.
          }
          • 2. Re: Why the ConcurrentModificationException?
            DrClap
            When you are going through a Set (or many other collections) using an Iterator, then any change to that Set will cause that exception to be thrown by the Iterator.

            And by using the for-loop you're using, you are using an Iterator. And line 152 in your code changes that Set. Hence, the exception.

            Personally I would get rid of the loop entirely and just use one of Set's built-in methods:
            medium.retainAll(memberMedium);
            • 3. Re: Why the ConcurrentModificationException?
              Owen Thomas
              Interesting stuff. Thank you both.
              • 4. Re: Why the ConcurrentModificationException?
                gimbal2
                DrClap wrote:
                medium.retainAll(memberMedium);
                And if retainAll or a similar method doesn't cut it, there is always the option of manually using an Iterator and using its remove() method to take out elements from a collection safely.

                (edit: as an addition to what Fahim posted)

                Edited by: gimbal2 on Apr 24, 2012 1:11 AM
                • 5. Re: Why the ConcurrentModificationException?
                  Owen Thomas
                  gimbal2 wrote:
                  DrClap wrote:
                  medium.retainAll(memberMedium);
                  And if retainAll or a similar method doesn't cut it, there is always the option of manually using an Iterator and using its remove() method to take out elements from a collection safely.

                  (edit: as an addition to what Fahim posted)

                  Edited by: gimbal2 on Apr 24, 2012 1:11 AM
                  Thanks for all your help.

                  I used retainAll to solve the problem I had quoted, but a similar problem appeared elsewhere, and I solved it by creating another collection using addAll to copy the first collection to a second collection, and then I used a foreach to iterate through the second one deleting appropriate members from the first. I assume there's no problem with doing things this way either. The reason why I created a second collection was that I like the foreach statement, and one can't use foreach statements with iterators.
                  • 6. Re: Why the ConcurrentModificationException?
                    gimbal2
                    Owen Thomas wrote:
                    I used retainAll to solve the problem I had quoted, but a similar problem appeared elsewhere, and I solved it by creating another collection using addAll to copy the first collection to a second collection, and then I used a foreach to iterate through the second one deleting appropriate members from the first. I assume there's no problem with doing things this way either. The reason why I created a second collection was that I like the foreach statement, and one can't use foreach statements with iterators.
                    Whatever makes you happy, but I wouldn't create such... unnecessary code only because you want to use foreach. Use the right tool for the job, not your favorite one.
                    • 7. Re: Why the ConcurrentModificationException?
                      Owen Thomas
                      gimbal2 wrote:
                      Owen Thomas wrote:
                      I used retainAll to solve the problem I had quoted, but a similar problem appeared elsewhere, and I solved it by creating another collection using addAll to copy the first collection to a second collection, and then I used a foreach to iterate through the second one deleting appropriate members from the first. I assume there's no problem with doing things this way either. The reason why I created a second collection was that I like the foreach statement, and one can't use foreach statements with iterators.
                      Whatever makes you happy, but I wouldn't create such... unnecessary code only because you want to use foreach. Use the right tool for the job, not your favorite one.
                      How is foreach any less necessary than a while loop?
                      • 8. Re: Why the ConcurrentModificationException?
                        Owen Thomas
                        One must assume that no response implies that there is no substantial difference, and that matters pertaining to whether one chooses to use an iterator in a while loop or a copy of a collection in a foreach loop are... trivial matters of style.

                        Edited by: Owen Thomas on Apr 24, 2012 6:40 PM
                        • 9. Re: Why the ConcurrentModificationException?
                          EJP
                          How is foreach any less necessary than a while loop?
                          It is 'less necessary' when it causes you to write code that throws ConcurrentModificationExceptions, and spend time on a forum because you couldn't figure it out, and use extra collections: none of which would have happened if you had used the while loop.
                          • 10. Re: Why the ConcurrentModificationException?
                            EJP
                            One must assume
                            No one mustn't. We already have one regular that starts posts that way, followed immediately by a non sequitur, as here. One is enough, thanks.
                            that no response implies that there is no substantial difference
                            Non sequitur.
                            and that matters pertaining to whether one chooses to use an iterator in a while loop or a copy of a collection in a foreach loop are... trivial matters of style.
                            ... unless you count the ConcurrentModificationExceptions, the extra collections, and the fact that you has to ask on this forum at all as a result.
                            • 11. Re: Why the ConcurrentModificationException?
                              796440
                              Owen Thomas wrote:
                              One must assume that no response implies that there is no substantial difference,
                              That's a pretty silly assumption.
                              and that matters pertaining to whether one chooses to use an iterator in a while loop or a copy of a collection in a foreach loop are... trivial matters of style.
                              There's also the fact that one creates a copy of the collection and the other does not. That could be a significant cost in time and space.
                              • 12. Re: Why the ConcurrentModificationException?
                                Owen Thomas
                                jverd wrote:
                                Owen Thomas wrote:
                                One must assume that no response implies that there is no substantial difference,
                                That's a pretty silly assumption.
                                No it isn't.

                                >
                                and that matters pertaining to whether one chooses to use an iterator in a while loop or a copy of a collection in a foreach loop are... trivial matters of style.
                                There's also the fact that one creates a copy of the collection and the other does not. That could be a significant cost in time and space.
                                Surely an iterator must also have a collection over which it iterates. If not, how does the creation of an iterator enable me to "iterate" over the collection when the size and content of the collection may change? Why wouldn't a second collection need to be created when one instantiates and iterator?

                                Providing me with a link to an article that discusses this would be appreciated.
                                • 13. Re: Why the ConcurrentModificationException?
                                  Owen Thomas
                                  EJP wrote:
                                  How is foreach any less necessary than a while loop?
                                  It is 'less necessary' when it causes you to write code that throws ConcurrentModificationExceptions, and spend time on a forum because you couldn't figure it out, and use extra collections: none of which would have happened if you had used the while loop.
                                  What I feel is necessary is for me to understand when and why an iterator would be good choice.
                                  • 14. Re: Why the ConcurrentModificationException?
                                    796440
                                    Owen Thomas wrote:
                                    jverd wrote:
                                    Owen Thomas wrote:
                                    One must assume that no response implies that there is no substantial difference,
                                    That's a pretty silly assumption.
                                    No it isn't.
                                    Yes, as a matter of fact it's totally ridiculous to think that the only reason someone doesn't respond to you is because you were correct. Believe it or not, people do have lives outside this forum, and proving something to you is not the center of our respective universes.
                                    and that matters pertaining to whether one chooses to use an iterator in a while loop or a copy of a collection in a foreach loop are... trivial matters of style.
                                    There's also the fact that one creates a copy of the collection and the other does not. That could be a significant cost in time and space.
                                    Surely an iterator must also have a collection over which it iterates.
                                    Yeah, the collection that already exists. What you're doing is creating an additional one beyond that, which is totally unnecessary here.
                                    If not, how does the creation of an iterator enable me to "iterate" over the collection when the size and content of the collection may change?
                                    Um, that's kind of the point of ConcurrentModificationException. If a modification occurs other than via the Iterator, then the Iterator's invariants may not hold, so that Iterator may not have an accurate picture of the state of the collection, which is why the exception is thrown.
                                    Providing me with a link to an article that discusses this would be appreciated.
                                    The javadocs for Collection and Iterator would be a start. You'll notice they say that the Iterator iterates over the Collection, and does not say anything about making a copy of it.
                                    1 2 3 4 Previous Next