【问题标题】:Why there 'foreach' loop generates an exception? [duplicate]为什么有'foreach'循环会产生异常? [复制]
【发布时间】:2019-10-17 09:12:36
【问题描述】:

我使用 Stack 和 StringBuilder 类编写了一个字符串反转代码。而且我注意到此代码中的“foreach”循环会生成 java.util.ConcurrentModificationException,但通常的“for”循环不会。那为什么呢?

public static String reverse(String str)
{
    Stack<Character> stack = new Stack<>();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < str.length(); i++)
        stack.push(str.toCharArray()[i]);
    }


    for (Character c: stack) // generates an exception
    {
        sb.append(stack.pop());
    }

    return sb.toString();
}

我期望一个反转的字符串,但发生了 ConcurrentModificationException。

【问题讨论】:

  • stack.push(str.toCharArray()[i]);不会像stack.push(str.charAt(i));while(!st.isEmpty()) { sb.append(stack.pop());}一样吗?
  • stack.pop() 修改栈,不允许改变foreach中的集合

标签: java


【解决方案1】:

在迭代堆栈时,您正在更改堆栈 (stack.pop())。尝试使用不同的循环:

public static String reverse(String str)
{
    Stack<Character> stack = new Stack<>();
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < str.length(); i++)
        stack.push(str.toCharArray()[i]);
    }


    while(!stack.isEmpty()){
         sb.append(stack.pop());
    }

    return sb.toString();
}

【讨论】:

    【解决方案2】:

    当您尝试编辑您正在迭代的内容时,会发生 ConcurrentModificationExceptions。通过调用stack.pop(),您正在从当前循环的实体中删除一个实体。

    我建议您遍历堆栈直到它为空:

    while (!stack.isEmpty()) {
        sb.append(stack.pop());
    }
    

    【讨论】:

      【解决方案3】:

      for-each 循环在后台使用一个迭代器,它检查“堆栈”中是否有下一个元素,然后将“字符 c”的值设置为下一个元素。但是你不能在 foreach 期间改变“堆栈”的大小。通过调用 stack.pop() 您违反了该规则。 而不是 for(Characater c : stack) 使用:

      while(!stack.empty()){
         sb.append(stack.pop());
      }
      

      【讨论】:

        【解决方案4】:

        pop 返回堆栈顶部的元素,然后删除该元素。在使用增强的 for 循环迭代集合时,您无法修改集合,因为正如您所见,您将获得 ConcurrentModificationException

        一种方法是使用while 循环并遍历堆栈直到其耗尽:

        while (!stack.empty()) {
            sb.append(stack.pop());
        }
        

        【讨论】:

          猜你喜欢
          • 2017-09-16
          • 2014-07-11
          • 2013-05-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-11-01
          • 1970-01-01
          相关资源
          最近更新 更多