• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Is my rationale correct?

 
Ranch Hand
Posts: 125
2
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

package com.udayan.oca;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class _12_Iterator_Question {
   public static void main(String[] args) {
       List<String> dryFruits = new ArrayList<>();
       dryFruits.add("Walnut");
       dryFruits.add("Apricot");   // iteration 2: removed
       dryFruits.add("Almond");    // iteration 3: attempts to remove and throws exception
       dryFruits.add("Date");

       Iterator<String> iterator = dryFruits.iterator();       // size 4
       while(iterator.hasNext()) {
           String dryFruit = iterator.next();
           if(dryFruit.startsWith("A")) {
               dryFruits.remove(dryFruit);
           }
       }

       System.out.println(dryFruits);
   }

       Answer is: Exception is thrown as on the third iteration you are reducing size of
       arraylist dryFruits to 2?
    */
 
Bartender
Posts: 1737
63
Eclipse IDE Postgres Database C++ Java
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your rationale is not correct, however, many would blame Iterator interface for being confusing.

When you are iterating thru a collection, you may use the iterator itself to remove an element.
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Iterator.html
Note that shows you a safe and effective way to remove an element.

If you use the general method to remove an element, it invalidates your iterator, which is unaware that the collection it is iterating thru has changed.

It is pretty confusing to see concurrent modification errors in single-threaded code.
They come about because the Iterator can only deal with removals it has performed itself.  Any other changes to the Collection it is iterating thru pull the rug out from under it.
 
Marshal
Posts: 80624
470
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please always tell us the source of such code.

Jesse Silverman wrote:. . . many would blame Iterator interface for being confusing. . . .

I think they would be blaming it unfairly. I think the Iterator documentation clearly says only to use the Iterator's methods to add or remove elements. The exception is called “concurrent” not because different threads are causing a problem, but because a change has occurred concurrently with the iteration of the List.
By the way: that is why Iterators should always be used as local variables. There is a tiny advantage to using this sort of loop instead of a while(): the Iterator goes out of scope sooner:-
 
Jesse Silverman
Bartender
Posts: 1737
63
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I'm going to agree with you Campbell (big surprise).

I think the real blame lies at the foot of those that present the enhanced for loop (not used here) as a one-stop easy solution, where it really just hides the iterator you would need to do this safely.

At a minimum, they should probably mention that it is  just hiding the iterator for us.

A better presentation would be that the enhanced for is fine for looking at one element at a time and doing something based on that.

The Iterator is fine for moving forward thru things explicitly and perhaps removing some of them (using the Iterator).

If you have a List, the ListIterator let's you move forward or back, and add, remove or update safely as well (thru the ListIterator).

I have seen presentations where the Spliterator was described as doing Iterators right, in ways additionally to parallelizability...better API, but older presentations and those that should perhaps be updated but have not been, never even mention it, leaving it sounding like something that will be used solely with Streams.

Which ties into a discussion I've seen here about how Streams API is often left as an "advanced" topic while they describe techniques available in 2005 as "normal" Java.

Interesting to me this weekend as I am dedicated to Streams for right now, hooping to make them part of my Go-to approach for coding, rather than as an advanced or exotic topic.
 
Campbell Ritchie
Marshal
Posts: 80624
470
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Jesse Silverman wrote:I'm going to agree with you Campbell . . .

We usually do agree . . . eventually.

mention that [for‑each] is  just hiding the iterator for us.

The JLS (=Java® Language Specification) is very clear about that. The Java™ Tutorials keep quiet about that.

A better presentation would be that the enhanced for is fine for looking at one element at a time and doing something based on that.

Agree (sorry ‍). I think of for‑each as iterating the whole of a data structure, only in a forward direction, and in “read‑only mode”.

. . . Spliterator was described as doing Iterators right, . . . .

Please explain more; I have never got my act together to learn about spliterators.
 
Jesse Silverman
Bartender
Posts: 1737
63
Eclipse IDE Postgres Database C++ Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Like a recent poster, I was in over my head watching a presentation done by someone who is in the Java source code as much as writing Applications, I don't have that link.

I haven't watched tons of his stuff yet, but this guy who teaches programming for a living has several good videos on Spliterators, I think he tries to get things right in his presentations rather than just going for big popularity, as he is a C.S. Professor for his day job (Note, I appreciate everyone trying to educate people for free, but as you know, some people don't bother to learn the material very well before they rush to present it and can accidentally confuse viewers rather badly):

https://www.youtube.com/watch?v=bwGasGTZhkY

My personal notes page on Iterator types looks like:
Enumeration -- Legacy, do not use in new code
Iterator -- Only goes forward, can look and remove only, but valid for all Collection types
ListIterator -- goes forward and back, can add, remove, update, but only for List
Spliterator -- these things are awesome, go learn about them (TBD)
 
Campbell Ritchie
Marshal
Posts: 80624
470
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Useful video: thank you. I was amused by the appearnce of != false on one of the earlier slides
 
reply
    Bookmark Topic Watch Topic
  • New Topic