For each and remove

  • Follow


With an old fashioned JDK 1.4 Iterator you can used the remove method
to remove an element without screwing up the looping.  Is it possible
to do the same thing using the JDK 1.5 for each loop syntax, say for
example to loop through an ArrayList or HashMap deleting some of the
elements?

--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
0
Reply Roedy 6/8/2007 10:18:02 PM

On Jun 8, 6:18 pm, Roedy Green <see_webs...@mindprod.com.invalid>
wrote:
> With an old fashioned JDK 1.4 Iterator you can used the remove method
> to remove an element without screwing up the looping.  Is it possible
> to do the same thing using the JDK 1.5 for each loop syntax, say for
> example to loop through an ArrayList or HashMap deleting some of the
> elements?
>
> --
> Roedy Green Canadian Mind Products
> The Java Glossaryhttp://mindprod.com


for(int i=list.size();i>=0;i--) {
  Object obj = list.get(i);
    if(needsToBeRemoved(i)) {
      list.remove(i);
    }
  }

0
Reply grasp06110 6/8/2007 10:58:37 PM


Roedy Green wrote:
> With an old fashioned JDK 1.4 Iterator you can used the remove method
> to remove an element without screwing up the looping.  Is it possible
> to do the same thing using the JDK 1.5 for each loop syntax, say for
> example to loop through an ArrayList or HashMap deleting some of the
> elements?

I don't think so, because you don't have a reference to the Iterator.

A far as I can tell, the enhanced for syntax is limited to a couple of
very specific cases. The basic for syntax is not deprecated and remains
perfectly appropriate for any loop that does not fit the enhanced for.

Patricia
0
Reply Patricia 6/8/2007 11:20:37 PM

Patricia Shanahan <pats@acm.org> writes:

> Roedy Green wrote:
>> With an old fashioned JDK 1.4 Iterator you can used the remove method
>> to remove an element without screwing up the looping.  Is it possible
>> to do the same thing using the JDK 1.5 for each loop syntax, say for
>> example to loop through an ArrayList or HashMap deleting some of the
>> elements?
>
> I don't think so, because you don't have a reference to the Iterator.
>
> A far as I can tell, the enhanced for syntax is limited to a couple of
> very specific cases. The basic for syntax is not deprecated and remains
> perfectly appropriate for any loop that does not fit the enhanced for.
>
> Patricia


The last paragraph on this page in the guide:
http://java.sun.com/j2se/1.5.0/docs/guide/language/foreach.html
would seems to confirm this.

Carl.
0
Reply Carl 6/8/2007 11:27:54 PM

On Fri, 08 Jun 2007 23:58:37 +0100, grasp06110 <grasp06110@yahoo.com>  =

wrote:

> On Jun 8, 6:18 pm, Roedy Green <see_webs...@mindprod.com.invalid>
> wrote:
>> With an old fashioned JDK 1.4 Iterator you can used the remove method=

>> to remove an element without screwing up the looping.  Is it possible=

>> to do the same thing using the JDK 1.5 for each loop syntax, say for
>> example to loop through an ArrayList or HashMap deleting some of the
>> elements?
>>
>> --
>> Roedy Green Canadian Mind Products
>> The Java Glossaryhttp://mindprod.com
>
>
> for(int i=3Dlist.size();i>=3D0;i--) {
>   Object obj =3D list.get(i);
>     if(needsToBeRemoved(i)) {
>       list.remove(i);
>     }
>   }

That ignores the main reason for using an Iterator in the first place.  =
If  =

the List isn't RandomAccess (i.e. it is a LinkedList rather than an  =

ArrayList), the performance will be bad (in a LinkedList, each call to g=
et  =

has to traverse the list to find the appropriate element).

Dan.


-- =

Daniel Dyer
http//www.uncommons.org
0
Reply Daniel 6/8/2007 11:34:55 PM

On Fri, 08 Jun 2007 15:58:37 -0700, grasp06110 <grasp06110@yahoo.com>
wrote, quoted or indirectly quoted someone who said :

>for(int i=list.size();i>=0;i--) {
>  Object obj = list.get(i);
>    if(needsToBeRemoved(i)) {
>      list.remove(i);
>    }
>  }

Your technique would skip processing the element after any removed
element.

here is the new entry in the Java Cheat Sheet

// I T E R A T O R - R E M O V E:
// efficiently removing elements from a List
// (ArrayList, LinkedList etc .
// or Collection.
// You can't remove elements with a for:each.
// This works faster than a get/remove.
// This approach avoids the effects of the List
// renumbering as you go which can cause you to 
// inadvertently skip elements or run off the end.
for ( Iterator<Item> iter = Items.iterator(); iter.hasNext(); )
   {
   Item item = iter.next();
   if ( item.isUnwanted() )
       {
       // remove from underlying Collection
       iter.remove();
       }
    }

--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
0
Reply Roedy 6/10/2007 11:05:32 PM

Roedy Green wrote:
> On Fri, 08 Jun 2007 15:58:37 -0700, grasp06110 <grasp06110@yahoo.com>
> wrote, quoted or indirectly quoted someone who said :
> 
>> for(int i=list.size();i>=0;i--) {
>>  Object obj = list.get(i);
>>    if(needsToBeRemoved(i)) {
>>      list.remove(i);
>>    }
>>  }
> 
> Your technique would skip processing the element after any removed
> element.

I don't see why. I do think the first index should be list.size()-1, not
list.size(). However, processing backwards, if done correctly, should
avoid changing the unprocessed portion of the list during a remove.

The iterator approach does seem better to me, because it is efficient
for any list type, even if an index scan is slow.

Patricia
0
Reply Patricia 6/11/2007 1:28:00 PM

Patricia Shanahan wrote:
> 
> The iterator approach does seem better to me, because it is efficient
> for any list type, even if an index scan is slow.

If roughly a constant fraction of the list is removed, then the 
algorithm is O(n^2) for a normal (array) list. Although it seems less 
efficient, it's in a sense better to filter while copying the and then 
copy back into the original list if necessary.

Tom Hawtin
0
Reply Tom 6/11/2007 6:32:18 PM

On Mon, 11 Jun 2007 00:05:32 +0100, Roedy Green  =

<see_website@mindprod.com.invalid> wrote:

> On Fri, 08 Jun 2007 15:58:37 -0700, grasp06110 <grasp06110@yahoo.com>
> wrote, quoted or indirectly quoted someone who said :
>
>> for(int i=3Dlist.size();i>=3D0;i--) {
>>  Object obj =3D list.get(i);
>>    if(needsToBeRemoved(i)) {
>>      list.remove(i);
>>    }
>>  }
>
> Your technique would skip processing the element after any removed
> element.

That's what I thought first time I read it, but (s)he is using the rathe=
r  =

devious trick of iterating over the collection backwards to avoid that  =

problem.  The main problem with this approach, as I mentioned the other =
 =

day, is that performance sucks if the list is long and does not support =
 =

random access (i.e. LinkedList).

> here is the new entry in the Java Cheat Sheet
>
> // I T E R A T O R - R E M O V E:
> // efficiently removing elements from a List
> // (ArrayList, LinkedList etc .
> // or Collection.
> // You can't remove elements with a for:each.
> // This works faster than a get/remove.
> // This approach avoids the effects of the List
> // renumbering as you go which can cause you to
> // inadvertently skip elements or run off the end.
> for ( Iterator<Item> iter =3D Items.iterator(); iter.hasNext(); )
>    {
>    Item item =3D iter.next();
>    if ( item.isUnwanted() )
>        {
>        // remove from underlying Collection
>        iter.remove();
>        }
>     }

For purely aesthetic reasons, I prefer the while loop variant (although =
 =

this does slightly widen the scope of the iterator reference).

Dan.

-- =

Daniel Dyer
http//www.uncommons.org
0
Reply Daniel 6/11/2007 6:57:50 PM

On Mon, 11 Jun 2007 13:28:00 GMT, Patricia Shanahan <pats@acm.org>
wrote, quoted or indirectly quoted someone who said :

>I don't see why. I do think the first index should be list.size()-1, not
>list.size(). However, processing backwards, if done correctly, should
>avoid changing the unprocessed portion of the list during a remove.

oops sorry.  I did not notice he was processing in reverse order.
--
Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com
0
Reply Roedy 6/13/2007 5:23:15 AM

9 Replies
207 Views

(page loaded in 0.094 seconds)

Similiar Articles:













7/25/2012 3:51:31 AM


Reply: