Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / August 2007

Tip: Looking for answers? Try searching our database.

How do you iterate over a List and remove elements?

Thread view: 
Knute Johnson - 24 Aug 2007 07:13 GMT
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,

Signature

Knute Johnson
email s/nospam/knute/

Patricia Shanahan - 24 Aug 2007 07:39 GMT
> 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
Frederick Polgardy - 24 Aug 2007 14:49 GMT
> > 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
[quoted text clipped - 6 lines]
>
> 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
Mike Schilling - 24 Aug 2007 07:49 GMT
> 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.
Ishwor Gurung - 24 Aug 2007 08:06 GMT
> 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

Signature

Cheers,
Ishwor Gurung
/* humpty dumpty */

bugbear - 24 Aug 2007 10:40 GMT
>> 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
[quoted text clipped - 9 lines]
> 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
Manish Pandit - 24 Aug 2007 15:09 GMT
On Aug 23, 11:13 pm, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
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
[quoted text clipped - 8 lines]
> 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 - 24 Aug 2007 15:11 GMT
> synchornize(list){

oops..synchronized(list){
Ben Phillips - 24 Aug 2007 15:37 GMT
>    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.
Patricia Shanahan - 24 Aug 2007 16:51 GMT
> On Aug 23, 11:13 pm, Knute Johnson <nos...@rabbitbrush.frazmtn.com>
> wrote:
[quoted text clipped - 20 lines]
>    }
> }

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
Manish Pandit - 24 Aug 2007 17:21 GMT
> 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
Patricia Shanahan - 24 Aug 2007 17:37 GMT
>> What is the purpose of the list.contains(obj) pre-check?
>
[quoted text clipped - 23 lines]
> -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
Manish Pandit - 24 Aug 2007 17:54 GMT
> What is the advantage of this, compared to the really dumb, simple,
> obvious approach using the Iterator remove() method?
[quoted text clipped - 6 lines]
>         }
>       }

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

-cheers,
Manish
Patricia Shanahan - 24 Aug 2007 18:25 GMT
>> What is the advantage of this, compared to the really dumb, simple,
>> obvious approach using the Iterator remove() method?
[quoted text clipped - 9 lines]
> 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
Joshua Cranmer - 24 Aug 2007 18:44 GMT
>> What is the advantage of this, compared to the really dumb, simple,
>> obvious approach using the Iterator remove() method?
[quoted text clipped - 9 lines]
> 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

Signature

Beware of bugs in the above code; I have only proved it correct, not
tried it. -- Donald E. Knuth

Knute Johnson - 25 Aug 2007 03:36 GMT
> 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
[quoted text clipped - 3 lines]
>
> Thanks,

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

Signature

Knute Johnson
email s/nospam/knute/

Roedy Green - 31 Aug 2007 06:28 GMT
On Thu, 23 Aug 2007 23:13:08 -0700, Knute Johnson
<nospam@rabbitbrush.frazmtn.com> 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
Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.