How do you iterate over a List and remove elements?

Discussion in 'Java' started by Knute Johnson, Aug 24, 2007.

  1. I've got an ArrayList and I want to iterate over the list and remove the
    occasional element. If I use the new for loop it throws a
    ConcurrentModificationException. An Iterator is going to have the same
    problem. There must be some simple way to do this that I'm not thinking
    of tonight.

    Thanks,

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Aug 24, 2007
    #1
    1. Advertising

  2. Knute Johnson wrote:
    > I've got an ArrayList and I want to iterate over the list and remove the
    > occasional element. If I use the new for loop it throws a
    > ConcurrentModificationException. An Iterator is going to have the same
    > problem. There must be some simple way to do this that I'm not thinking
    > of tonight.


    Use an explicit Iterator-based loop, and the Iterator's remove method,
    not the underlying collection's remove.

    Patricia
    Patricia Shanahan, Aug 24, 2007
    #2
    1. Advertising

  3. Knute Johnson wrote:
    > I've got an ArrayList and I want to iterate over the list and remove
    > the occasional element. If I use the new for loop it throws a
    > ConcurrentModificationException. An Iterator is going to have the
    > same problem.


    The ConcurrentModificationException occurs because you're modifying the List
    behind the Iterator's back, so to speak. If you use the Iterator to do the
    removes you'll be fine.
    Mike Schilling, Aug 24, 2007
    #3
  4. Knute Johnson wrote:

    > I've got an ArrayList and I want to iterate over the list and remove the
    > occasional element. If I use the new for loop it throws a
    > ConcurrentModificationException. An Iterator is going to have the same


    The API docs say that ConcurrentModificationException is thrown when you try
    to delete an elment in the array list while the iterator is busy traversing
    the elements inside it.

    > problem. There must be some simple way to do this that I'm not thinking
    > of tonight.


    Yes indeed there is. One way to do it is if you can find an element that
    you'd like to delete then check it first, delete it and then break out.
    Iterator i = l.iterator();
    while(i.hasNext())
    {
    if (i.next().equals("a"))
    {
    //the key point is breaking out here
    l.remove("a");break;
    }
    }

    If you want to delete the whole list, why traverse it in the first place? ;)
    hth

    --
    Cheers,
    Ishwor Gurung
    /* humpty dumpty */
    Ishwor Gurung, Aug 24, 2007
    #4
  5. Knute Johnson

    bugbear Guest

    Ishwor Gurung wrote:
    > Knute Johnson wrote:
    >
    >> I've got an ArrayList and I want to iterate over the list and remove the
    >> occasional element. If I use the new for loop it throws a
    >> ConcurrentModificationException. An Iterator is going to have the same

    >
    > The API docs say that ConcurrentModificationException is thrown when you try
    > to delete an elment in the array list while the iterator is busy traversing
    > the elements inside it.
    >
    >> problem. There must be some simple way to do this that I'm not thinking
    >> of tonight.

    >
    > Yes indeed there is. One way to do it is if you can find an element that
    > you'd like to delete then check it first, delete it and then break out.


    The ConcurrentModificationException is caused by the Iterator
    "noticing" that you've changed something under its feet.

    The proper solution is to "play nice" with the iterator,
    and remove the element AND keep the iterator informed.

    http://java.sun.com/j2se/1.4.2/docs/api/java/util/Iterator.html#remove()

    BugBear
    bugbear, Aug 24, 2007
    #5
  6. On Aug 24, 1:39 am, Patricia Shanahan <> wrote:
    > Knute Johnson wrote:
    > > I've got an ArrayList and I want to iterate over the list and remove the
    > > occasional element. If I use the new for loop it throws a
    > > ConcurrentModificationException. An Iterator is going to have the same
    > > problem. There must be some simple way to do this that I'm not thinking
    > > of tonight.

    >
    > Use an explicit Iterator-based loop, and the Iterator's remove method,
    > not the underlying collection's remove.
    >
    > Patricia


    In other words:

    Iterator i = l.iterator();
    while (i.hasNext()) {
    if (shouldRemove(i.next()) {
    i.remove();
    }
    }

    You can remove as many elements as you need to in the same iteration.

    Fred
    Frederick Polgardy, Aug 24, 2007
    #6
  7. On Aug 23, 11:13 pm, Knute Johnson <>
    wrote:
    > I've got an ArrayList and I want to iterate over the list and remove the
    > occasional element. If I use the new for loop it throws a
    > ConcurrentModificationException. An Iterator is going to have the same
    > problem. There must be some simple way to do this that I'm not thinking
    > of tonight.
    >
    > Thanks,
    >
    > --
    >
    > Knute Johnson
    > email s/nospam/knute/


    If you are removing one occassional element, you can just remove it
    without iterating (or may be I did not get the situation). Something
    like:

    synchornize(list){
    if(list.contains(obj){
    list.remove(obj);
    }
    }

    -cheers,
    Manish
    Manish Pandit, Aug 24, 2007
    #7
  8. On Aug 24, 7:09 am, Manish Pandit <> wrote:

    > synchornize(list){


    oops..synchronized(list){
    Manish Pandit, Aug 24, 2007
    #8
  9. Knute Johnson

    Ben Phillips Guest

    Manish Pandit wrote:
    > if(list.contains(obj){
    > list.remove(obj);
    > }


    Collections let you do coll.remove(obj) whether or not it's definitely
    in there to remove, and return a boolean in case you want to do
    something different depending on whether it was there to remove or it
    wasn't. This is more efficient as the linked list, array, hash table,
    tree, or other backing data structure gets searched only once instead of
    twice.
    Ben Phillips, Aug 24, 2007
    #9
  10. Manish Pandit wrote:
    > On Aug 23, 11:13 pm, Knute Johnson <>
    > wrote:
    >> I've got an ArrayList and I want to iterate over the list and remove the
    >> occasional element. If I use the new for loop it throws a
    >> ConcurrentModificationException. An Iterator is going to have the same
    >> problem. There must be some simple way to do this that I'm not thinking
    >> of tonight.
    >>
    >> Thanks,
    >>
    >> --
    >>
    >> Knute Johnson
    >> email s/nospam/knute/

    >
    > If you are removing one occassional element, you can just remove it
    > without iterating (or may be I did not get the situation). Something
    > like:
    >
    > synchornize(list){
    > if(list.contains(obj){
    > list.remove(obj);
    > }
    > }


    That technique works if you want to remove an item with a specified
    value. Suppose, for example, you want to remove every string shorter
    than 3 characters from a List<String>. It can be done easily using the
    Iterator remove method.

    What is the purpose of the list.contains(obj) pre-check?

    Patricia
    Patricia Shanahan, Aug 24, 2007
    #10
  11. On Aug 24, 8:51 am, Patricia Shanahan <> wrote:

    > What is the purpose of the list.contains(obj) pre-check?
    >


    My bad..did not realize contains returns a boolean. Been thinking
    about this for a while, and I was wondering if it makes sense to use
    an array (or another list..a clone) as an intermediatory. I know this
    has scalability and performance numbers against it though. Here is a
    little snippet:

    ArrayList<Integer> list = new ArrayList<Integer>();
    for(int i=0; i<10; i++){
    list.add(i);
    }
    //remove all the even numbers
    Integer[] array = new Integer[list.size()];
    list.toArray(array);
    for( int i:array ){
    if( i%2==0 ) {
    list.remove(new Integer(i));
    }
    }
    System.out.println(list);

    Ofcourse this needs to be synchronized, to make sure the array and the
    list do not go out of sync.

    -cheers,
    Manish
    Manish Pandit, Aug 24, 2007
    #11
  12. Manish Pandit wrote:
    > On Aug 24, 8:51 am, Patricia Shanahan <> wrote:
    >
    >> What is the purpose of the list.contains(obj) pre-check?
    >>

    >
    > My bad..did not realize contains returns a boolean. Been thinking
    > about this for a while, and I was wondering if it makes sense to use
    > an array (or another list..a clone) as an intermediatory. I know this
    > has scalability and performance numbers against it though. Here is a
    > little snippet:
    >
    > ArrayList<Integer> list = new ArrayList<Integer>();
    > for(int i=0; i<10; i++){
    > list.add(i);
    > }
    > //remove all the even numbers
    > Integer[] array = new Integer[list.size()];
    > list.toArray(array);
    > for( int i:array ){
    > if( i%2==0 ) {
    > list.remove(new Integer(i));
    > }
    > }
    > System.out.println(list);
    >
    > Ofcourse this needs to be synchronized, to make sure the array and the
    > list do not go out of sync.
    >
    > -cheers,
    > Manish
    >


    What is the advantage of this, compared to the really dumb, simple,
    obvious approach using the Iterator remove() method?


    //remove all the even numbers
    Iterator<Integer> it = list.iterator();
    while(it.hasNext()){
    if(it.next() % 2 == 0){
    it.remove();
    }
    }

    Patricia
    Patricia Shanahan, Aug 24, 2007
    #12
  13. On Aug 24, 9:37 am, Patricia Shanahan <> wrote:
    > What is the advantage of this, compared to the really dumb, simple,
    > obvious approach using the Iterator remove() method?
    >
    > //remove all the even numbers
    > Iterator<Integer> it = list.iterator();
    > while(it.hasNext()){
    > if(it.next() % 2 == 0){
    > it.remove();
    > }
    > }
    >


    Not a whole lot except that it is not guaranteed that the Iterator
    will support remove().

    -cheers,
    Manish
    Manish Pandit, Aug 24, 2007
    #13
  14. Manish Pandit wrote:
    > On Aug 24, 9:37 am, Patricia Shanahan <> wrote:
    >> What is the advantage of this, compared to the really dumb, simple,
    >> obvious approach using the Iterator remove() method?
    >>
    >> //remove all the even numbers
    >> Iterator<Integer> it = list.iterator();
    >> while(it.hasNext()){
    >> if(it.next() % 2 == 0){
    >> it.remove();
    >> }
    >> }
    >>

    >
    > Not a whole lot except that it is not guaranteed that the Iterator
    > will support remove().


    It is for ArrayList, and any other List that inherits the AbstractList
    iterator method and itself supports remove(int):

    "This implementation returns a straightforward implementation of the
    iterator interface, relying on the backing list's size(), get(int), and
    remove(int) methods."

    Patricia
    Patricia Shanahan, Aug 24, 2007
    #14
  15. Manish Pandit wrote:
    > On Aug 24, 9:37 am, Patricia Shanahan <> wrote:
    >> What is the advantage of this, compared to the really dumb, simple,
    >> obvious approach using the Iterator remove() method?
    >>
    >> //remove all the even numbers
    >> Iterator<Integer> it = list.iterator();
    >> while(it.hasNext()){
    >> if(it.next() % 2 == 0){
    >> it.remove();
    >> }
    >> }
    >>

    >
    > Not a whole lot except that it is not guaranteed that the Iterator
    > will support remove().


    Nor is it guaranteed that a Collection will support remove() (e.g.,
    unmodifiableList). The number of implementations where the list supports
    remove() and the iterator doesn't is probably about zero.
    >
    > -cheers,
    > Manish
    >



    --
    Beware of bugs in the above code; I have only proved it correct, not
    tried it. -- Donald E. Knuth
    Joshua Cranmer, Aug 24, 2007
    #15
  16. Knute Johnson wrote:
    > I've got an ArrayList and I want to iterate over the list and remove the
    > occasional element. If I use the new for loop it throws a
    > ConcurrentModificationException. An Iterator is going to have the same
    > problem. There must be some simple way to do this that I'm not thinking
    > of tonight.
    >
    > Thanks,
    >


    Thanks everybody. That's what I was looking for.

    --

    Knute Johnson
    email s/nospam/knute/
    Knute Johnson, Aug 25, 2007
    #16
  17. Knute Johnson

    Roedy Green Guest

    On Thu, 23 Aug 2007 23:13:08 -0700, Knute Johnson
    <> wrote, quoted or indirectly quoted
    someone who said :

    >I've got an ArrayList and I want to iterate over the list and remove the
    >occasional element. If I use the new for loop it throws a
    >ConcurrentModificationException


    see http://mindprod.com/jgloss/jcheat.html#LOOPS
    --
    Roedy Green Canadian Mind Products
    The Java Glossary
    http://mindprod.com
    Roedy Green, Aug 31, 2007
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Gogo
    Replies:
    1
    Views:
    2,083
    Sudsy
    Sep 4, 2003
  2. runescience
    Replies:
    0
    Views:
    1,439
    runescience
    Feb 9, 2006
  3. John Salerno
    Replies:
    29
    Views:
    603
    bruno at modulix
    May 22, 2006
  4. John Salerno
    Replies:
    0
    Views:
    486
    John Salerno
    Jun 2, 2006
  5. Alexander
    Replies:
    11
    Views:
    798
    Richard Damon
    Sep 30, 2011
Loading...

Share This Page