Linkedlist error when removing using an iterator [duplicate] - java

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
LinkedList iterator remove
private LinkedList flights;
...
public FlightQueue() {
super();
flights = new LinkedList();
}
...
public void clear(){
ListIterator itr = flights.listIterator();
while(itr.hasNext()){
itr.remove();
}
}
....
Exception in thread "main" java.lang.IllegalStateException
at java.util.LinkedList$ListItr.remove(Unknown Source)
at section1.FlightQueue.clear(FlightQueue.java:44)
at section1.FlightTest001.main(FlightTest001.java:22)
No idea whats wrong, its showing the error at the first itr.remove().

From the iterator API:
IllegalStateException - if the next method
has not yet been called, or the remove method has already been called
after the last call to the next method
you have to call iterator.next() before calling iterator.remove().
while(itr.hasNext()){
itr.next(); //This would resolve the exception.
itr.remove();
}

You can call itr.remove() only if you called next() or previous() before, because it removes an element that was returned by those methods.
public void clear(){
flights.clear();
}

Use clear() method of LinkedList

Have a look at the Javadoc for ListIterator. It specifically states:
IllegalStateException - neither next nor previous have been called,
or remove or add have been called after the last call to next or previous.
You'll need a .next() before the .remove() in your posted code fragment.
Cheers,

Related

Why the iterator throws a exception for Integer linkedlist [duplicate]

In the code below I have a try catch block that attempts to remove an element from a Vector, using Iterator. I've created my own class QueueExtendingVect that extends Vector and implements Iterator.
The variable qev1 is an instance of class QueueExtendingVect. I've already added a few elements to this Vector as well.
try
{
qev1.iterator().remove();
}
catch(UnsupportedOperationException e)
{
System.out.println("Calling Iterator.remove() and throwing exception.");
}
qev1.enqueue(ci);
qev2.enqueue(ci);
qcv1.enqueue(ci);
qcv2.enqueue(ci);
for (int i = 1; i < 5; i++)
{
if (i % 2 == 0)
{
qev1.enqueue(new CInteger(i+1));
qev2.enqueue(new CInteger(i+1));
qcv1.enqueue(new CInteger(i+1));
qcv2.enqueue(new CInteger(i+1));
}
else
{
qev1.enqueue(new Date(i*i));
qev2.enqueue(new Date(i*i));
qcv1.enqueue(new Date(i*i));
qcv2.enqueue(new Date(i*i));
}
}
In this code I add a few elements to the Vector qev1. The other variables are in other parts of the code.
However, when I run my program I get an IllegalStateException at runtime. I'm not sure what this means.
You haven't called next() on your Iterator, so it's not referring to the first item yet. You can't remove the item that isn't specified yet.
Call next() to advance to the first item first, then call remove().
#rgettman answer is correct but to give you imagination.
Our collection: |el1| |el2| |el3|
when you call iterator.next() it works this way:
|el1| iterator |el2| |el3|
so it jumps over the element and return reference to the element which was jumped (|el1|). So if we called iterator.remove() now, |el1| would be removed.
It's worth to add what #PedroBarros mentioned above - you can't call iterator.remove() two times without iterator.next() between them because IllegalStateException would be thrown.
Also when you create two iterators (iterator1, iterator2) then calling:
iterator1.next();
iterator1.remove();
iterator2.next();
will throw ConcurrentModificationException because iterator2 checks that collection was modified.
It will also call this exeption, If you add something to the list in iterator and then after it not calling it.next() again but removing the item

ConcurrentModificationException -> How can I change my code to stop it from throwing this error? [duplicate]

This question already has answers here:
Iterating through a Collection, avoiding ConcurrentModificationException when removing objects in a loop
(31 answers)
Closed 5 years ago.
for (FPlayer p : fPlayer.getFaction().getOnline()) {
p.setFaction(null);
}
Basically, the getOnline method returns an array list of the current FPlayers that are online. When the FPlayer is removed from their faction, the faction is set to null (p.setFaction(null)).
I cannot think about how to change my code to stop it from throwing the ConcurrentModificationException. I have used an iterator but still, it.next().setFaction(null) still throws the same exception.
EDIT:
USING A LIST ITERATOR:
ListIterator<FPlayer> it = fPlayer.getFaction().getOnline().listIterator();
while (it.hasNext()) {
it.next().setFaction(null);
}
Caused by: java.util.ConcurrentModificationException
At the line
it.next().setFaction(null)
EDIT #2:
Set faction method:
public void setFaction(Faction faction) {
if (hasFaction()) {
this.faction.getOnline().remove(this);
}
this.faction = faction;
if (faction != null) {
this.faction.getOnline().add(this);
}
}
This is happening because while iterating you are removing the data from the list .
Couple of solutions .
If the list size is small convert it to array and then loop over
Use for loop for iteration .
for(int i=0;i<fPlayer.getFaction().getOnline().size();i++)
{
// Condition to check if true
if(true)
{
fPlayer.getFaction().getOnline().remove(i);
i--;
}
}
Yes, change your code so it doesn't change the collection inside the loop you are running. For example, create a copy of the collection before iterating.
for (Foo foo : new ArrayList(myFoos)) {
if (foo.isBar()) {
myFoos.remove(foo);
}
}
Iterating and changing the list without the new ArrayList() would have caused a ConcurrentModificationException

ConcurrentModificationException in iterator.next() Multithreaded [duplicate]

This question already has answers here:
ConcurrentModificationException when using iterator and iterator.remove()
(4 answers)
Closed 6 years ago.
I have created this simple worker thread to calculate palindromes by iterating through an ArrayList.
I get an Error when I execute line temp_str1 = it.next();.
The ArrayList buffer_List is not used by any other thread hence using synchronized block does not help. I have looked through previous questions and they did not help much. I would eager to find the solution to this problem.
Here is My code:
private void find_Palindromes(ArrayList<String> buffer_List){
Iterator<String> it = buffer_List.iterator();
String temp_str1, temp_str2;
while(it.hasNext()){
temp_str1 = it.next();
//System.out.println(temp_str1);
it.remove();
if(is_Palindrome(temp_str1)){
to_Shared_Queue(temp_str1);
palin_count++;
}
}
}
Edit Code : added to_Shared_Queue
private void to_Shared_Queue(String str){
synchronized(shared_queue){
Shared_queue.add(str);
}
}
It is because of you modifying iterator while looping over it . you can do it by remove it from your array buffer_List.
buffer_List.remove(temp_str1);

Recursion logic from Iterating over iterator and so on

Can anybody help me with recursion logic? I have a iterator object, on which I am iterating using while loop. Then in each iterated object I again have to iterate and so on.
private void handleRecursiveMethod(someMethod) {
Iterator<Sometype> methods=doingSomething(someMethod));
while(methods.hasNext()){
printingDetailsAboutThisMethod(methods.next())
// Again with each method I have to do same
// operation until methods.hasNext becomes false.
handleRecursiveMethod(methods.next());
// By calling this, it does not complete while
// loop first time.
}
}
Your function goes into while loop till the iterator has no more entries to iterate on. So I think when you call handleRecursiveMethod(methods.next()); at the end of the method, it should be throwing you a NoSuchElementException.
From your example, it seems to be that you are trying to do a depth first traversal. So, your code should look something like
private void handleRecursiveMethod(Sometype someMethod) {
Iterator<Sometype> methods=doingSomething(someMethod));
while(methods.hasNext()){
Sometype method = methods.next()
printingDetailsAboutThisMethod(method)
handleRecursiveMethod(method);
}
}

Iterator.remove() IllegalStateException

In the code below I have a try catch block that attempts to remove an element from a Vector, using Iterator. I've created my own class QueueExtendingVect that extends Vector and implements Iterator.
The variable qev1 is an instance of class QueueExtendingVect. I've already added a few elements to this Vector as well.
try
{
qev1.iterator().remove();
}
catch(UnsupportedOperationException e)
{
System.out.println("Calling Iterator.remove() and throwing exception.");
}
qev1.enqueue(ci);
qev2.enqueue(ci);
qcv1.enqueue(ci);
qcv2.enqueue(ci);
for (int i = 1; i < 5; i++)
{
if (i % 2 == 0)
{
qev1.enqueue(new CInteger(i+1));
qev2.enqueue(new CInteger(i+1));
qcv1.enqueue(new CInteger(i+1));
qcv2.enqueue(new CInteger(i+1));
}
else
{
qev1.enqueue(new Date(i*i));
qev2.enqueue(new Date(i*i));
qcv1.enqueue(new Date(i*i));
qcv2.enqueue(new Date(i*i));
}
}
In this code I add a few elements to the Vector qev1. The other variables are in other parts of the code.
However, when I run my program I get an IllegalStateException at runtime. I'm not sure what this means.
You haven't called next() on your Iterator, so it's not referring to the first item yet. You can't remove the item that isn't specified yet.
Call next() to advance to the first item first, then call remove().
#rgettman answer is correct but to give you imagination.
Our collection: |el1| |el2| |el3|
when you call iterator.next() it works this way:
|el1| iterator |el2| |el3|
so it jumps over the element and return reference to the element which was jumped (|el1|). So if we called iterator.remove() now, |el1| would be removed.
It's worth to add what #PedroBarros mentioned above - you can't call iterator.remove() two times without iterator.next() between them because IllegalStateException would be thrown.
Also when you create two iterators (iterator1, iterator2) then calling:
iterator1.next();
iterator1.remove();
iterator2.next();
will throw ConcurrentModificationException because iterator2 checks that collection was modified.
It will also call this exeption, If you add something to the list in iterator and then after it not calling it.next() again but removing the item

Categories

Resources