Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #36275 > unrolled thread
| Started by | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| First post | 2017-02-15 16:56 -0600 |
| Last post | 2017-02-16 23:21 +0100 |
| Articles | 10 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
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
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-02-15 16:56 -0600 |
| Subject | Removing 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]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2017-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]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-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]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2017-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]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-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]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2017-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]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2017-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]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2017-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]
| From | v_borchert@despammed.com (Volker Borchert) |
|---|---|
| Date | 2017-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]
| From | Robert Klemme <shortcutter@googlemail.com> |
|---|---|
| Date | 2017-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