Reputation: 103
So this is just a dummy program to understand list Iterator. Steps that im doing
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.
Upvotes: 4
Views: 636
Reputation: 925
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".
Upvotes: 1
Reputation: 270790
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");
}
}
Upvotes: 2
Reputation: 393771
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.
Upvotes: 3