4

So this is just a dummy program to understand list Iterator. Steps that im doing

  1. created a ArrayList with "A" and "B"
  2. Now created a listIterator for this ArrayList
  3. If "B"is found ill add "C" next to it
  4. If "A" is found ill replace it with "a"
  5. If "B" is found ill replace it with "b".

Code:

public class Main {
    public static void main(String[]  args) {
        ArrayList<String> al = new ArrayList<String>();
        al.add("A");
        al.add("B");

        ListIterator lItr = al.listIterator();
        while(lItr.hasNext()) {
        String s = (String)lItr.next();
        System.out.println(s);
        if(s.equals("B")) {
            lItr.add("C");
        }
        if(s.equals("A")) {
            lItr.set("a");
        }
        else if(s.equals("B")) {
            lItr.set("b");//Im getting an exception here saying
                            "java.lang.IllegalStateException"
        }
        }
        System.out.println(al);
    }
}

Please anyone tell why am i getting this exception why cant i set "B" to b.

Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Follow this https://stackoverflow.com/questions/20169127/what-is-illegalstateexception –  Dec 05 '18 at 07:43
  • Did you read the [documentation](https://docs.oracle.com/javase/8/docs/api/java/util/ListIterator.html#set-E-)? – shmosel Dec 05 '18 at 07:45
  • Note that if you declared the type of `lItr` as `ListIterator`, you wouldn't need the cast in `String s = (String)lItr.next();` – Andy Turner Dec 05 '18 at 08:53

3 Answers3

3

You are calling lItr.add("C") followed by lItr.set("b") without calling next or previous in between.

void java.util.ListIterator.set(Object e)

Replaces the last element returned by next or previous with the specified element (optional operation). This call can be made only if neither remove nor add have been called after the last call to next or previous.

Eran
  • 387,369
  • 54
  • 702
  • 768
2

The documentation clearly says why this happens:

Throws:

UnsupportedOperationException - if the set operation is not supported by this list iterator

ClassCastException - if the class of the specified element prevents it from being added to this list

IllegalArgumentException - if some aspect of the specified element prevents it from being added to this list

IllegalStateException - if neither next nor previous have been called, or remove or add have been called after the last call to next or previous

You have called add before calling set, right?

if(s.equals("B")) {
    lItr.add("C"); // <-- here!
}
if(s.equals("A")) {
    lItr.set("a");
}
else if(s.equals("B")) {
    lItr.set("b"); // <-- and here
}

After you have added an element, the element you will set changes, so that is not allowed.

To fix this, simply do the add after the set:

 // Also use generic types properly!
ListIterator<String> lItr = al.listIterator();
while(lItr.hasNext()) {
    String s = lItr.next();
    System.out.println(s);
    if(s.equals("A")) {
        lItr.set("a");
        lItr.add("C"); // note the change here
    }
    else if(s.equals("B")) {
        lItr.set("b");
    }
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
1

As per the Java documentation https://docs.oracle.com/javase/8/docs/api/java/util/ListIterator.html#set-E-

void set(E e)

Replaces the last element returned by next() or previous() with the specified element (optional operation). This call can be made only if neither remove() nor add(E) have been called after the last call to next or previous.

You are calling lItr.add("C") and then lItr.set("b"), with no call to next() or previous() in between, because both if conditions are checking for s.equals("B") and both of them will evaluate to true if the element is "B".

if(s.equals("B")) {
    lItr.add("C");
}

else if(s.equals("B")) {
    lItr.set("b");//Im getting an exception here saying
                    "java.lang.IllegalStateException"
}

This execution path occurs since you do not have an ELSE in the second IF condition, which makes the third IF condition run after the first IF is executed if element is "B".

A_C
  • 905
  • 6
  • 18