Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #36275 > unrolled thread

Removing an element while iterating over a List with enhanced for?

Started byKnute Johnson <nospam@rabbitbrush.frazmtn.com>
First post2017-02-15 16:56 -0600
Last post2017-02-16 23:21 +0100
Articles 10 — 5 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Removing an element while iterating over a List with enhanced for? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-02-15 16:56 -0600
    Re: Removing an element while iterating over a List with enhanced for? Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-02-15 18:24 -0500
      Re: Removing an element while iterating over a List with enhanced for? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-02-15 17:51 -0600
    Re: Removing an element while iterating over a List with enhanced for? Arne Vajhøj <arne@vajhoej.dk> - 2017-02-15 22:43 -0500
      Re: Removing an element while iterating over a List with enhanced for? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-02-16 11:17 -0600
        Re: Removing an element while iterating over a List with enhanced for? Robert Klemme <shortcutter@googlemail.com> - 2017-02-16 18:30 +0100
          Re: Removing an element while iterating over a List with enhanced for? Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2017-02-16 11:35 -0600
          Re: Removing an element while iterating over a List with enhanced for? Arne Vajhøj <arne@vajhoej.dk> - 2017-02-16 14:02 -0500
          Re: Removing an element while iterating over a List with enhanced for? v_borchert@despammed.com (Volker Borchert) - 2017-02-16 20:09 +0000
            Re: Removing an element while iterating over a List with enhanced for? Robert Klemme <shortcutter@googlemail.com> - 2017-02-16 23:21 +0100

#36275 — Removing an element while iterating over a List with enhanced for?

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-02-15 16:56 -0600
SubjectRemoving an element while iterating over a List with enhanced for?
Message-ID<o82m7a$tls$1@dont-email.me>
An enhanced for loop on a List is no different than using an Iterator 
right?  So is there any problem removing the current element from the 
list while using the enhanced for loop?  I couldn't find anything that 
said it was OK or not OK in the JLS.

import java.util.*;
import java.util.stream.*;
import static java.util.stream.Collectors.*;

public class test9 {
     public static void main(String... args) {
         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());

         for (Integer i : list)
             if (i == 9)
                 list.remove(i);

         list.forEach(System.out::println);

         list = Stream.of(1,5,7,9,13).collect(toList());

         Iterator<Integer> iter = list.iterator();

         while (iter.hasNext())
             if (iter.next() == 9)
                 iter.remove();

         list.forEach(System.out::println);
     }
}

Thanks,

-- 

Knute Johnson

[toc] | [next] | [standalone]


#36276

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2017-02-15 18:24 -0500
Message-ID<o82nr7$5me$1@dont-email.me>
In reply to#36275
On 2/15/2017 5:56 PM, Knute Johnson wrote:
> An enhanced for loop on a List is no different than using an Iterator
> right?  So is there any problem removing the current element from the
> list while using the enhanced for loop?  I couldn't find anything that
> said it was OK or not OK in the JLS.

     1) During an iteration, you can only remove elements through
the Iterator's own remove() method.

     2) The enhanced `for' does indeed use an Iterator, but it
doesn't expose the Iterator instance: You have no way to refer
to it.

     3) Since you can't get a reference to the Iterator, you can't
call the Iterator's remove().

     Therefore,

     4) You can't remove anything while executing an enhanced `for'.

>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>
>         for (Integer i : list)
>             if (i == 9)
>                 list.remove(i);

     Not permitted.  From the Javadoc for Iterator#remove: "The behavior
of an iterator is unspecified if the underlying collection is modified
while the iteration is in progress in any way other than by calling
this method."

     Just for fun, I tried your example -- and it worked!!!  But that's
one of the possible outcomes of "unspecified" behavior, and I rather
suspected that it "worked" because the removed element just happened
to be the penultimate and the Iterator's hasNext() might have returned
false.  So I changed `9' to `7' to attack an earlier element, and got

Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at esosman.misc.Knute.main(Knute.java:15)

>         while (iter.hasNext())
>             if (iter.next() == 9)
>                 iter.remove();

     This is the correct approach.

-- 
esosman@comcast-dot-net.invalid
One thousand four hundred thirty-five days to go.

[toc] | [prev] | [next] | [standalone]


#36277

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-02-15 17:51 -0600
Message-ID<o82peg$abt$1@dont-email.me>
In reply to#36276
On 2/15/2017 17:24, Eric Sosman wrote:
> On 2/15/2017 5:56 PM, Knute Johnson wrote:
>> An enhanced for loop on a List is no different than using an Iterator
>> right?  So is there any problem removing the current element from the
>> list while using the enhanced for loop?  I couldn't find anything that
>> said it was OK or not OK in the JLS.
>
>     1) During an iteration, you can only remove elements through
> the Iterator's own remove() method.
>
>     2) The enhanced `for' does indeed use an Iterator, but it
> doesn't expose the Iterator instance: You have no way to refer
> to it.
>
>     3) Since you can't get a reference to the Iterator, you can't
> call the Iterator's remove().
>
>     Therefore,
>
>     4) You can't remove anything while executing an enhanced `for'.
>
>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>>
>>         for (Integer i : list)
>>             if (i == 9)
>>                 list.remove(i);
>
>     Not permitted.  From the Javadoc for Iterator#remove: "The behavior
> of an iterator is unspecified if the underlying collection is modified
> while the iteration is in progress in any way other than by calling
> this method."
>
>     Just for fun, I tried your example -- and it worked!!!  But that's
> one of the possible outcomes of "unspecified" behavior, and I rather
> suspected that it "worked" because the removed element just happened
> to be the penultimate and the Iterator's hasNext() might have returned
> false.  So I changed `9' to `7' to attack an earlier element, and got
>
> Exception in thread "main" java.util.ConcurrentModificationException
>     at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
>     at java.util.ArrayList$Itr.next(ArrayList.java:851)
>     at esosman.misc.Knute.main(Knute.java:15)
>
>>         while (iter.hasNext())
>>             if (iter.next() == 9)
>>                 iter.remove();
>
>     This is the correct approach.
>

Thanks!
-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36279

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-02-15 22:43 -0500
Message-ID<o83759$lhe$1@gioia.aioe.org>
In reply to#36275
On 2/15/2017 5:56 PM, Knute Johnson wrote:
> An enhanced for loop on a List is no different than using an Iterator
> right?  So is there any problem removing the current element from the
> list while using the enhanced for loop?  I couldn't find anything that
> said it was OK or not OK in the JLS.

>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>
>         for (Integer i : list)
>             if (i == 9)
>                 list.remove(i);
>
>         list.forEach(System.out::println);
>
>         list = Stream.of(1,5,7,9,13).collect(toList());
>
>         Iterator<Integer> iter = list.iterator();
>
>         while (iter.hasNext())
>             if (iter.next() == 9)
>                 iter.remove();
>
>         list.forEach(System.out::println);

Since you are already using streams and lambdas then why not:

list = list.stream().filter(v -> v != 9).collect(toList());

?

Arne

[toc] | [prev] | [next] | [standalone]


#36290

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-02-16 11:17 -0600
Message-ID<o84mo2$lrp$1@dont-email.me>
In reply to#36279
On 2/15/2017 21:43, Arne Vajhøj wrote:
> On 2/15/2017 5:56 PM, Knute Johnson wrote:
>> An enhanced for loop on a List is no different than using an Iterator
>> right?  So is there any problem removing the current element from the
>> list while using the enhanced for loop?  I couldn't find anything that
>> said it was OK or not OK in the JLS.
>
>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>>
>>         for (Integer i : list)
>>             if (i == 9)
>>                 list.remove(i);
>>
>>         list.forEach(System.out::println);
>>
>>         list = Stream.of(1,5,7,9,13).collect(toList());
>>
>>         Iterator<Integer> iter = list.iterator();
>>
>>         while (iter.hasNext())
>>             if (iter.next() == 9)
>>                 iter.remove();
>>
>>         list.forEach(System.out::println);
>
> Since you are already using streams and lambdas then why not:
>
> list = list.stream().filter(v -> v != 9).collect(toList());
>
> ?
>
> Arne
>
>

That's where I'm going eventually.  The real code is a lot more complex 
and I got distracted by something that shouldn't have worked :-).

-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36291

FromRobert Klemme <shortcutter@googlemail.com>
Date2017-02-16 18:30 +0100
Message-ID<egm5srFomftU1@mid.individual.net>
In reply to#36290
On 16.02.2017 18:17, Knute Johnson wrote:
> On 2/15/2017 21:43, Arne Vajhøj wrote:
>> On 2/15/2017 5:56 PM, Knute Johnson wrote:
>>> An enhanced for loop on a List is no different than using an Iterator
>>> right?  So is there any problem removing the current element from the
>>> list while using the enhanced for loop?  I couldn't find anything that
>>> said it was OK or not OK in the JLS.
>>
>>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());

Btw. I know it is just the code to get a list filled but still you can 
have that much simpler:

     list = Arrays.asList(1, 5, 7, 9, 13);

We tend to forget the "good ole code" over all the fancy new things.  :-)

Cheers

	robert


-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [next] | [standalone]


#36292

FromKnute Johnson <nospam@rabbitbrush.frazmtn.com>
Date2017-02-16 11:35 -0600
Message-ID<o84npp$qfv$1@dont-email.me>
In reply to#36291
On 2/16/2017 11:30, Robert Klemme wrote:
> On 16.02.2017 18:17, Knute Johnson wrote:
>> On 2/15/2017 21:43, Arne Vajhøj wrote:
>>> On 2/15/2017 5:56 PM, Knute Johnson wrote:
>>>> An enhanced for loop on a List is no different than using an Iterator
>>>> right?  So is there any problem removing the current element from the
>>>> list while using the enhanced for loop?  I couldn't find anything that
>>>> said it was OK or not OK in the JLS.
>>>
>>>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>
> Btw. I know it is just the code to get a list filled but still you can
> have that much simpler:
>
>     list = Arrays.asList(1, 5, 7, 9, 13);
>
> We tend to forget the "good ole code" over all the fancy new things.  :-)
>
> Cheers
>
>     robert
>
>

It was a bad day yesterday, that's all I can say.

-- 

Knute Johnson

[toc] | [prev] | [next] | [standalone]


#36296

FromArne Vajhøj <arne@vajhoej.dk>
Date2017-02-16 14:02 -0500
Message-ID<o84t00$1k5r$2@gioia.aioe.org>
In reply to#36291
On 2/16/2017 12:30 PM, Robert Klemme wrote:
> On 16.02.2017 18:17, Knute Johnson wrote:
>> On 2/15/2017 21:43, Arne Vajhøj wrote:
>>> On 2/15/2017 5:56 PM, Knute Johnson wrote:
>>>> An enhanced for loop on a List is no different than using an Iterator
>>>> right?  So is there any problem removing the current element from the
>>>> list while using the enhanced for loop?  I couldn't find anything that
>>>> said it was OK or not OK in the JLS.
>>>
>>>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>
> Btw. I know it is just the code to get a list filled but still you can
> have that much simpler:
>
>     list = Arrays.asList(1, 5, 7, 9, 13);
>
> We tend to forget the "good ole code" over all the fancy new things.  :-)

Note though that Java 9:

list = List.of(1, 5, 7, 9, 13);

will not work!

Arne

[toc] | [prev] | [next] | [standalone]


#36308

Fromv_borchert@despammed.com (Volker Borchert)
Date2017-02-16 20:09 +0000
Message-ID<o850tb$e7n$1@Gaia.teknon.de>
In reply to#36291
Robert Klemme wrote:
> On 16.02.2017 18:17, Knute Johnson wrote:
> > On 2/15/2017 21:43, Arne Vajh??j wrote:
> >> On 2/15/2017 5:56 PM, Knute Johnson wrote:
> >>> An enhanced for loop on a List is no different than using an Iterator
> >>> right?  So is there any problem removing the current element from the
> >>> list while using the enhanced for loop?  I couldn't find anything that
> >>> said it was OK or not OK in the JLS.
> >>
> >>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
> 
> Btw. I know it is just the code to get a list filled but still you can 
> have that much simpler:
> 
>      list = Arrays.asList(1, 5, 7, 9, 13);
> 
> We tend to forget the "good ole code" over all the fancy new things.  :-)

The list you get from this does not support removal.

-- 

"I'm a doctor, not a mechanic." Dr Leonard McCoy <mccoy@ncc1701.starfleet.fed>
"I'm a mechanic, not a doctor." Volker Borchert  <v_borchert@despammed.com>

[toc] | [prev] | [next] | [standalone]


#36313

FromRobert Klemme <shortcutter@googlemail.com>
Date2017-02-16 23:21 +0100
Message-ID<egmmvbFs6skU1@mid.individual.net>
In reply to#36308
On 16.02.2017 21:09, Volker Borchert wrote:
> Robert Klemme wrote:
>> On 16.02.2017 18:17, Knute Johnson wrote:
>>> On 2/15/2017 21:43, Arne Vajh??j wrote:
>>>> On 2/15/2017 5:56 PM, Knute Johnson wrote:
>>>>> An enhanced for loop on a List is no different than using an Iterator
>>>>> right?  So is there any problem removing the current element from the
>>>>> list while using the enhanced for loop?  I couldn't find anything that
>>>>> said it was OK or not OK in the JLS.
>>>>
>>>>>         List<Integer> list = Stream.of(1,5,7,9,13).collect(toList());
>>
>> Btw. I know it is just the code to get a list filled but still you can
>> have that much simpler:
>>
>>      list = Arrays.asList(1, 5, 7, 9, 13);
>>
>> We tend to forget the "good ole code" over all the fancy new things.  :-)
>
> The list you get from this does not support removal.

Correct.  Slightly less simple

     list = new ArrayList<>(Arrays.asList(1, 5, 7, 9, 13));

I concede it's not so nice any more. :-)

Cheers

	robert

-- 
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web