2

Without further delay, I will post my code straight away. It is very simple so you shouldn't find any problems understanding it. My idea is to add color after it found "blue" using listIterator. Apparently there is something wrong here.

public class Main {
    public static void main(String[] args) {
        Color c1 = new Color("red");
        Color c2 = new Color("blue");
        Color c3 = new Color("green");

        List<Color> list = new ArrayList<>();
        list.add(c1);
        list.add(c2);
        list.add(c3);

        ListIterator<Color> iterator = list.listIterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
            if (iterator.next().tone.equals("blue")){
                iterator.add(new Color("yellow"));
            }
        }

    }
}

class Color {
    String tone;

    public Color(String tone) {
        this.tone = tone;
    }

    @Override
    public String toString() {
        return tone;
    }
}

OUTPUT:

red
green
Exception in thread "main" java.util.NoSuchElementException
    at java.base/java.util.ArrayList$Itr.next(ArrayList.java:999)
    at Main.main(Main.java:21)
Stefan
  • 969
  • 6
  • 9

2 Answers2

2

You call hasNext() once for 2 calls of next(). Call it once and save it to be able to use multiple times

while (iterator.hasNext()){
     Color current = iterator.next();
     System.out.println(current);
     if (current.tone.equals("blue")){
         iterator.add(new Color("yellow"));
     }
}
azro
  • 53,056
  • 7
  • 34
  • 70
  • Thanks azro! Could you help me understand the name of that exception `noSuchElement`? Because `next()` technically didn't remove my **element**, it just moved the cursor. – Stefan Sep 27 '20 at 20:14
  • @Stefan "Hi I want the next element please", "Sorry there no such one in my actual iterator" there no "next" element from the position we are now, all the ones have be consumed – azro Sep 27 '20 at 20:16
  • True, I finally get it :) Although `.next()` is in if loop, it is still calling `next()`. That is what you are saying? So eventually in last call there will be no more elements and I call `next()`. Right? – Stefan Sep 27 '20 at 20:34
  • 1
    @Stefan Yes the `.next()` in the if DOES move the cursor forward, each call of next() does, so with hasNext you're sure that you can do 1 move, but you were doing 2 – azro Sep 27 '20 at 20:35
1

I know the answer is provided but posting if it helps refer below code:-

public static void main(String[] args) {
    Color c1 = new Color("red");
    Color c2 = new Color("blue");
    Color c3 = new Color("green");

    List<Color> list = new ArrayList<>();
    list.add(c1);
    list.add(c2);
    list.add(c3);

    ListIterator<Color> iterator = list.listIterator();
    System.out.println(iterator.next());//-->red
    System.out.println(iterator.next());//-->blue
    System.out.println(iterator.next());//-->green
    System.out.println(iterator.next());//-->java.util.NoSuchElementException (iterator is moved forward but list is exhausted)
}

so basically iterator.next() locates the element in the iterable collection. hence calling iterator.next() multiple time in ur while loop will shift the cursor eveytime to next value , hence its better to store iterator.next() into a variable inside the loop.

Amit Kumar Lal
  • 5,537
  • 3
  • 19
  • 37