我尝试将ArrayList
实现为我正在制作的内容,但无论何时我在循环中向ArrayList
添加新项目,我都会得到ConcurrentModificationError
1}},这是有道理但我不知道如何解决这个问题。
我的代码如下所示:
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");
}
}
}
错误肯定不是来自它自己的对象,并且在draw()中调用make()函数时会发生错误。
非常感谢任何帮助,谢谢。
答案 0 :(得分:1)
使用ListIterator
进行迭代并添加到列表中。
for (ListIterator<Pipe> iter = pipes.listIterator(); iter.hasNext();) {
Pipe p = iter.next();
[...]
make(iter);
}
然后在make:
iter.add(new Pipe());
来自ListIterator
的javadoc:
列表的迭代器,允许程序员在任一方向遍历列表,在迭代期间修改列表,并获取迭代器在列表中的当前位置。
您可以添加到迭代器,而不是添加到列表中。在这种情况下没有并发修改,因为迭代器能够跟踪列表更改。
请注意,iter.add()
调用会在iter.next()
返回的元素之前添加元素。这意味着新添加的对象不会是列表中的最后一个。这通常是首选,因为您不希望干扰循环的前向流,即您不希望循环的下一次迭代在新添加的对象上。但是你的情况可能会有所不同。
答案 1 :(得分:1)
我建议您使用CopyOnWriteArrayList。
这将允许列表中的突变,同时通过生成基础数组的副本来保留迭代器的完整性。
当然,这会带来性能成本。
尝试一下(我扼杀了你没有提供实现的方法):
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class Test {
private int width;
private class Pipe {
public int x;
public void display() {
}
public void move() {
}
public void create() {
}
}
List<Pipe> pipes;
void size(int w, int h) {
}
public void background(int i) {
}
void setup() {
size(640, 360);
pipes = new CopyOnWriteArrayList<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();
System.out.println("A");
}
}
}
public static void main(String[] args) {
Test t = new Test();
t.setup();
t.draw();
}
}