首页 > 解决方案 > Java: `iterator.remove` throws IllegalStateException

问题描述

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.

标签: javaiteratorillegalstateexception

解决方案


Iterator.java 删除方法:

    @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() {
        ..
    }

问题出在您的 for 循环“查找并删除重复记录”中,您可能不止一次调用 iterator.remove。remove 方法会删除您正在查看的当前元素,因此您每次使用 next() 只能调用一次。为确保它只被调用一次,请在break下面添加一条语句iterator.remove();


推荐阅读