Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 处理中的ConcurrentModificationException_Java_Processing - Fatal编程技术网

Java 处理中的ConcurrentModificationException

Java 处理中的ConcurrentModificationException,java,processing,Java,Processing,我试图在我正在制作的东西中实现一个ArrayList,但是每当我从循环中向ArrayList添加一个新项目时,我会得到一个ConcurrentModificationError,这很有意义,但我不知道如何解决这个问题 我的代码如下所示: ArrayList<Pipe> pipes; void setup() { size(640, 360); pipes = new ArrayList<Pipe>(); make(); } void make() { p

我试图在我正在制作的东西中实现一个
ArrayList
,但是每当我从循环中向
ArrayList
添加一个新项目时,我会得到一个
ConcurrentModificationError
,这很有意义,但我不知道如何解决这个问题

我的代码如下所示:

ArrayList<Pipe> pipes;

void setup() {
  size(640, 360);
  pipes = new ArrayList<Pipe>();
  make();
}
void make() {
  pipes.add(new Pipe());
  Pipe P = pipes.get((pipes.size()-1));
  P.create();
}

void draw() {
  background(255);
  for (Pipe p : pipes) {
    p.display();
    p.move();
    if (p.x < 3*width/4) {
      make();
      println("A");
    }  
  }
}
ArrayList管道;
无效设置(){
尺寸(640360);
管道=新的ArrayList();
make();
}
使无效{
管道。添加(新管道());
pipep=pipes.get((pipes.size()-1));
P.创建();
}
作废提款(){
背景(255);
用于(管道p:管道){
p、 显示();
p、 move();
如果(p.x<3*宽度/4){
make();
println(“A”);
}  
}
}
错误肯定不是来自对象本身,错误发生在draw()中调用make()函数时

任何帮助都将不胜感激,谢谢。

使用a进行迭代并添加到列表中

for (ListIterator<Pipe> iter = pipes.listIterator(); iter.hasNext();) {
    Pipe p = iter.next();
    [...]
    make(iter);
}
for(ListIterator iter=pipes.ListIterator();iter.hasNext();){
管道p=iter.next();
[...]
make(iter);
}
然后在制造中:

iter.add(新管道())

列表迭代器的javadoc中:

列表的迭代器,允许程序员沿任意方向遍历列表,在迭代过程中修改列表,并获取迭代器在列表中的当前位置

您将添加到迭代器,而不是添加到列表中。在这种情况下没有并发修改,因为迭代器能够跟踪列表更改

请注意,
iter.add()
调用将在
iter.next()
返回的元素之前添加元素。这意味着新添加的对象不会是列表中的最后一个对象。这通常更可取,因为您不希望干扰循环的正向流,即不希望循环的下一次迭代在新添加的对象上。但您的情况可能会有所不同。

使用a进行迭代并添加到列表中

for (ListIterator<Pipe> iter = pipes.listIterator(); iter.hasNext();) {
    Pipe p = iter.next();
    [...]
    make(iter);
}
for(ListIterator iter=pipes.ListIterator();iter.hasNext();){
管道p=iter.next();
[...]
make(iter);
}
然后在制造中:

iter.add(新管道())

列表迭代器的javadoc中:

列表的迭代器,允许程序员沿任意方向遍历列表,在迭代过程中修改列表,并获取迭代器在列表中的当前位置

您将添加到迭代器,而不是添加到列表中。在这种情况下没有并发修改,因为迭代器能够跟踪列表更改

请注意,
iter.add()
调用将在
iter.next()
返回的元素之前添加元素。这意味着新添加的对象不会是列表中的最后一个对象。这通常更可取,因为您不希望干扰循环的正向流,即不希望循环的下一次迭代在新添加的对象上。但是您的情况可能会有所不同。

我建议您使用一种新的方法

这将允许对列表进行变异,同时通过创建底层数组的副本来保持迭代器的完整性

当然,这是以性能为代价的

尝试一下(我删除了您调用的方法,但没有提供实现):

import java.util.List;
导入java.util.concurrent.CopyOnWriteArrayList;
公开课考试{
私有整数宽度;
专用管道{
公共int x;
公共空间显示(){
}
公开作废动议(){
}
公共void create(){
}
}
列出管道清单;
空隙大小(整数w,整数h){
}
公共空间背景(int i){
}
无效设置(){
尺寸(640360);
管道=新的CopyOnWriteArrayList();
make();
}
使无效{
管道。添加(新管道());
pipep=pipes.get((pipes.size()-1));
P.创建();
}
作废提款(){
背景(255);
用于(管道p:管道){
p、 显示();
p、 move();
如果(p.x<3*宽度/4){
make();
系统输出打印项次(“A”);
}
}
}
公共静态void main(字符串[]args){
测试t=新测试();
t、 设置();
t、 draw();
}
}
我建议使用一个

这将允许对列表进行变异,同时通过创建底层数组的副本来保持迭代器的完整性

当然,这是以性能为代价的

尝试一下(我删除了您调用的方法,但没有提供实现):

import java.util.List;
导入java.util.concurrent.CopyOnWriteArrayList;
公开课考试{
私有整数宽度;
专用管道{
公共int x;
公共空间显示(){
}
公开作废动议(){
}
公共void create(){
}
}
列出管道清单;
空隙大小(整数w,整数h){
}
公共空间背景(int i){
}
无效设置(){
尺寸(640360);
管道=新的CopyOnWriteArrayList();
make();
}
使无效{
管道。添加(新管道());
pipep=pipes.get((pipes.size()-1));
P.创建();
}
作废提款(){
背景(255);
用于(管道p:管道){
p、 显示();
p、 move();
如果(p.x<3*宽度/4){
make();
系统输出打印项次(“A”);
}
}
}
公共静态void main(字符串[]args){
测试t=新测试();
t、 设置();
t、 draw();
}
}

您正在
make
中添加一个新的
pipe
,它使
foreach
中使用的迭代器无效:如果编写
pipe P=new pipe(),代码不是会更好/更明显/更清晰吗;白痢