Java:递归函数中出现意外的运行时错误

Java:递归函数中出现意外的运行时错误,java,recursion,concurrentmodification,Java,Recursion,Concurrentmodification,我正在尝试编写自己版本的MergeSort,并编写了以下类: import java.util.List; import java.util.LinkedList; import java.lang.Comparable; public class Sort<E extends Comparable<E>> { private List<E> list; public void setList(List<E> inList) {list

我正在尝试编写自己版本的MergeSort,并编写了以下类:

import java.util.List;
import java.util.LinkedList;
import java.lang.Comparable;

public class Sort<E extends Comparable<E>> {
  private List<E> list;

  public void setList(List<E> inList) {list = inList;}
  public List<E> getList() {return list;}

  public List<E> mergeSortRec(List<E> inList) {
    if (inList == null) return null;
    if (inList.size() < 2) return inList;
    int mdpt = inList.size()/2;
    List<E> left = inList.subList(0,mdpt);
    List<E> right = inList.subList(mdpt,inList.size());
    left = mergeSortRec(left);
    right = mergeSortRec(right);
    List<E> out = new LinkedList<E>();
    while (left.size()>0 && right.size()>0) {
      if (left.get(0).compareTo(right.get(0)) < 0) {
        out.add(left.remove(0));
      } else {
        out.add(right.remove(0));
      }
    }
    if (left.size()==0) {
      while (right.size()>0) {
        out.add(right.remove(0));
      }
    } else {
      while (left.size()>0) {
        out.add(left.remove(0));
      }
    }
    return out;
  }
  public void mergeSort() {list = mergeSortRec(list);}
}

插入打印行后,我发现问题来自
if(left.size()==0){
中对
left.size()
的调用,我相信它发生在“第零级”对于递归调用,也就是说,它发生在
inList
是整个原始列表的时候,
left
是3,
right
是1,5。我不明白为什么对
left
的方法调用会导致错误。我只是模糊不清地理解了为什么会出现一些并发问题,但我几乎没有经验h这一点,我认为可以避免,因为
left
是一个函数的返回值,因此不应该被多个变量引用——如果这与问题有关的话。

这里的问题是由于从正在迭代的列表中删除了一个项:

 while (left.size()>0 && right.size()>0) { // iteration on left/right lists
      if (left.get(0).compareTo(right.get(0)) < 0) {
        out.add(left.remove(0)); // modification of the left list
      } else {
        out.add(right.remove(0)); // modification of the right list
      }
 }
while(left.size()>0&&right.size()>0){//左/右列表上的迭代
if(left.get(0).compareTo(right.get(0))<0{
out.add(left.remove(0));//修改左侧列表
}否则{
out.add(right.remove(0));//修改右列表
}
}
在while迭代期间删除项违反了列表对象的约定,并导致异常-

处理这个问题有多种方法-

  • 在对原始列表进行迭代时,使用将被修改的列表的副本。在这种情况下,您可以使用大小计数器而不是调用lists size方法
  • 使用和迭代器的专用
    remove()
    方法
  • 在Java8中,您可以使用该方法
参考资料:


这实际上解释了很多问题,不仅仅是我的问题,还有为什么我看到其他人使用位置跟踪器实现MergeSort——这本来可以避免这个问题。@Addem:很高兴我能帮助buddy。
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.SubList.checkForComodification(AbstractList.java:769)
    at java.util.SubList.size(AbstractList.java:645)
    at Sort.mergeSortRec(Sort.java:69)
    at Sort.mergeSortRec(Sort.java:59)
    at Sort.mergeSort(Sort.java:79)
    at Main.main(Main.java:12)
 while (left.size()>0 && right.size()>0) { // iteration on left/right lists
      if (left.get(0).compareTo(right.get(0)) < 0) {
        out.add(left.remove(0)); // modification of the left list
      } else {
        out.add(right.remove(0)); // modification of the right list
      }
 }