【问题标题】:Iteration Illegalstate exeption when comparing lists比较列表时迭代非法状态异常
【发布时间】:2019-09-29 01:14:19
【问题描述】:

我试图通过使用迭代器来获取数组列表中的类似项目。 我一直遇到这个错误:

Exception in thread "main" java.lang.IllegalStateException
at java.util.ArrayList$Itr.remove(ArrayList.java:872)
at com.fryslan.updater.wrappers.MethodDataItem.getIntListSimilarities(MethodDataItem.java:97)
at com.fryslan.updater.wrappers.MethodDataItem.matchAbstractNodes(MethodDataItem.java:67)
at com.fryslan.updater.wrappers.MethodDataItem.equals(MethodDataItem.java:182)
at com.fryslan.updater.Updater.<init>(Updater.java:57)
at com.fryslan.updater.Updater.main(Updater.java:99)

我使用的代码是这样的:

 private ArrayList<Integer> getIntListSimilarities(ArrayList<Integer> base, ArrayList<Integer> target) {

    ArrayList<Integer> matching = new ArrayList<>();
    Iterator baseIterator = base.listIterator();
    Iterator targetIterator = target.listIterator();

    while (baseIterator.hasNext()) {
        while (targetIterator.hasNext()) {

            int bv = (int) baseIterator.next();
            int tv = (int) targetIterator.next();

            if (bv == tv) {
                matching.add(bv);
                baseIterator.remove();
                targetIterator.remove();
                baseIterator = base.listIterator();
                targetIterator = target.listIterator();
            }
        }
    }

    return matching;
}

【问题讨论】:

    标签: java arraylist iterator


    【解决方案1】:

    您的代码有很多问题。例如,如果输入是 [1] 和 [1,2],它将抛出 NoSuchElementException:

    baseIterator.remove(); // remove the element from ArrayList<Integer> base
    ...
    baseIterator = base.listIterator(); // new Iterator from the base that had its element removed
    ...
    while (targetIterator.hasNext()); // looking at the 2nd Integer in [1,2]
    ...
    int bv = (int) baseIterator.next(); // NoSuchElementException
    

    此外,如果base 的元素多于target,您的代码可能会进入无限循环(查看base 的最后一个元素时,第一个循环始终为true,第二个循环始终为false )。

    这里,IllegalStateException 可能是因为您在空的ArrayList 上调用remove,但是我无法重现该问题。


    如果您无法使用此提示修复代码,我将添加解决方案。

    提示:将两个循环合并为一个,在一个 while 循环中同时评估两个条件 hasNext

    【讨论】:

    • 当然就是这样!我对迭代不是很熟悉,所以我像处理循环一样处理它。合并 hasNexts 修复它。感谢您的帮助。
    【解决方案2】:

    这完成了工作。

     private ArrayList<Integer> getIntListSimilarities(ArrayList<Integer> base, ArrayList<Integer> target) {
    
        ArrayList<Integer> matching = new ArrayList<>();
        Iterator baseIterator = base.listIterator();
        Iterator targetIterator = target.listIterator();
    
        while (baseIterator.hasNext() && targetIterator.hasNext()) {
    
            int bv = (int) baseIterator.next();
            int tv = (int) targetIterator.next();
    
            if (bv == tv) {
                matching.add(bv);
                baseIterator.remove();
                targetIterator.remove();
            }
        }
    
        return matching;
    }
    

    【讨论】:

      【解决方案3】:

      不使用迭代器就可以得到两个List&lt;Integer&gt; 的共同元素。 IllegalStateException 可能会被抛出,因为您在迭代时重置迭代器与行

      baseIterator = base.listIterator();
      targetIterator = target.listIterator();
      

      我真的认为这样做没有任何意义。

      这是一个如何找到两个列表的共同元素的示例,它需要 Java 8

      public static List<Integer> getCommonElementsOf(List<Integer> firstList, List<Integer> secondList) {
          List<Integer> commonElements = new ArrayList<Integer>();
      
          firstList.forEach(element -> {
              if (secondList.contains(element)) {
                  commonElements.add(element);
              }
          });
      
          return commonElements;
      }
      

      这也可以使用经典循环来完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多