I have an iterator
inside a thread
and I am trying to remove the duplicate records.
Runnable readingThread = new Runnable() {
@Override
public void run() {
Iterator<Demand> iterator = null;
for (iterator = demandListFromFile.iterator(); iterator.hasNext();) {
Demand demand = iterator.next();
/**
* Find and assign the Item ID
*/
if (itemListHashMap.containsValue(demand.getItem().getItemName())) {
demand.getItem().setIditem(itemListHashMapReversed.get(demand.getItem().getItemName()));
} else {
unavailableItemsList.add(demand.getItem().getItemName());
}
/**
* Find and remove duplicate records
*/
for (Map.Entry<Date, String> entry : demandListHashMap.entries()) {
if (demand.getDueDate().equals(entry.getKey()) && demand.getItem().getItemName().equals(entry.getValue())) {
iterator.remove();
}
}
}
}
After removing few items, the iterator.remove
throws the below exception
Exception in thread "Thread-0" java.lang.IllegalStateException
at java.base/java.util.ArrayList$Itr.remove(ArrayList.java:1009)
at com.xxx.xxx.ui.Home$7.run(Home.java:455)
at java.base/java.lang.Thread.run(Thread.java:834)
Why is this happening? Please note I have removed the code after and before the iterator, to keep this post short.
Iterator.java remove method:
@throws 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
void remove() {
..
}
The problem is in your for loop "Find and remove duplicate records" you may be calling iterator.remove more than once. The remove method removes the current element you are viewing so you can only call it once per using next(). To ensure it's called only once, add a break
statement below iterator.remove();
The reason stated by @CausingUnderflowsEverywhere was absolutely right.
Adding to that, after seeing the implementation, iterator.remove
element calls the ArrayList.remove
method internally.
ArrayList is maintaining the index of the last element returned in a variable called lastRet
Once the element is removed, the ArrayList.remove method set the lastRet
to -1.
And the very first check of ArrayList.remove is
if (lastRet < 0)
{
throw new IllegalStateException();
}
This is what happens in the background.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.