从 arraylist 中删除对象正在做奇怪的事情
remove objects from arraylist is doing strange things
在下面的代码中,我希望球从 ArrayList ballList
变为另一个 ArrayList oldBalls
,只要它们的年龄高于阈值。
这段代码应该很简单,但我不明白为什么当年龄与阈值相同(不是更大)时它们消失然后在 2 帧后返回。
我已经在 java 中使用 ArrayLists 的迭代器检查了相关问题,但我认为应该有一种方法可以在没有 java 的情况下进行处理。
另外,我似乎无法 post 在处理论坛上提出任何问题,即使我可以登录,也不知道为什么...
我已将代码减少到能够重现错误的最低限度。
ArrayList <Ball> ballList;
ArrayList <Ball> oldBalls;
int threshold=4;
PFont font;
void setup(){
size(400,400);
frameRate(0.5);
font=createFont("Georgia", 18);
textFont(font);
textAlign(CENTER, CENTER);
ballList=new ArrayList<Ball>();
oldBalls=new ArrayList<Ball>();
noFill();
strokeWeight(2);
}
void draw(){
background(0);
Ball b=new Ball(new PVector(10, random(height/10,9*height/10)),new PVector(10,0),0);
ballList.add(b);
stroke(0,0,200);
for(int i=0;i<oldBalls.size();i++){
Ball bb=oldBalls.get(i);
bb.update();
bb.render();
text(bb.age,bb.pos.x,bb.pos.y);
}
stroke(200,0,0);
for(int i=0;i<ballList.size();i++){
Ball bb=ballList.get(i);
bb.update();
bb.render();
bb.migrate();
text(bb.age,bb.pos.x,bb.pos.y);
}
}
class Ball{
PVector pos;
PVector vel;
int age;
Ball(PVector _pos, PVector _vel, int _age){
pos=_pos;
vel=_vel;
age=_age;
}
void migrate(){
if(age>threshold){
oldBalls.add(this);
ballList.remove(this);
}
}
void update(){
pos.add(vel);
age+=1;
}
void render(){
ellipse(pos.x,pos.y,24,24);
}
}
注意标有 age=threshold 的球是如何突然消失的...
我猜问题出在这里:
for(int i=0;i<ballList.size();i++){
Ball bb=ballList.get(i);
bb.update();
bb.render();
//add this
if(bb.migrate())
i--;
text(bb.age,bb.pos.x,bb.pos.y);
}
和
boolean migrate(){
if(age>threshold){
oldBalls.add(this);
ballList.remove(this);
//and this
return true;
}
return false;
}
migrate()
将从 ballList 中删除对象并将其大小减小 1。
这里看起来像是因为您在遍历列表的同时更改列表。考虑一下你在这里的这个 for 循环
for(int i=0;i<ballList.size();i++){
Ball bb=ballList.get(i);
bb.update();
bb.render();
bb.migrate();
text(bb.age,bb.pos.x,bb.pos.y);
}
假设 ballList 中有 2 个球都是 3 岁,第一个循环获取 ball[0] 然后将其从列表中删除,我将递增并且循环将立即退出,因为 ballList.size() 是现在 1. 所以不是到达 4 岁的球消失了,而是随后的球消失了。
在下面的代码中,我希望球从 ArrayList ballList
变为另一个 ArrayList oldBalls
,只要它们的年龄高于阈值。
这段代码应该很简单,但我不明白为什么当年龄与阈值相同(不是更大)时它们消失然后在 2 帧后返回。
我已经在 java 中使用 ArrayLists 的迭代器检查了相关问题,但我认为应该有一种方法可以在没有 java 的情况下进行处理。 另外,我似乎无法 post 在处理论坛上提出任何问题,即使我可以登录,也不知道为什么...
我已将代码减少到能够重现错误的最低限度。
ArrayList <Ball> ballList;
ArrayList <Ball> oldBalls;
int threshold=4;
PFont font;
void setup(){
size(400,400);
frameRate(0.5);
font=createFont("Georgia", 18);
textFont(font);
textAlign(CENTER, CENTER);
ballList=new ArrayList<Ball>();
oldBalls=new ArrayList<Ball>();
noFill();
strokeWeight(2);
}
void draw(){
background(0);
Ball b=new Ball(new PVector(10, random(height/10,9*height/10)),new PVector(10,0),0);
ballList.add(b);
stroke(0,0,200);
for(int i=0;i<oldBalls.size();i++){
Ball bb=oldBalls.get(i);
bb.update();
bb.render();
text(bb.age,bb.pos.x,bb.pos.y);
}
stroke(200,0,0);
for(int i=0;i<ballList.size();i++){
Ball bb=ballList.get(i);
bb.update();
bb.render();
bb.migrate();
text(bb.age,bb.pos.x,bb.pos.y);
}
}
class Ball{
PVector pos;
PVector vel;
int age;
Ball(PVector _pos, PVector _vel, int _age){
pos=_pos;
vel=_vel;
age=_age;
}
void migrate(){
if(age>threshold){
oldBalls.add(this);
ballList.remove(this);
}
}
void update(){
pos.add(vel);
age+=1;
}
void render(){
ellipse(pos.x,pos.y,24,24);
}
}
注意标有 age=threshold 的球是如何突然消失的...
我猜问题出在这里:
for(int i=0;i<ballList.size();i++){
Ball bb=ballList.get(i);
bb.update();
bb.render();
//add this
if(bb.migrate())
i--;
text(bb.age,bb.pos.x,bb.pos.y);
}
和
boolean migrate(){
if(age>threshold){
oldBalls.add(this);
ballList.remove(this);
//and this
return true;
}
return false;
}
migrate()
将从 ballList 中删除对象并将其大小减小 1。
这里看起来像是因为您在遍历列表的同时更改列表。考虑一下你在这里的这个 for 循环
for(int i=0;i<ballList.size();i++){
Ball bb=ballList.get(i);
bb.update();
bb.render();
bb.migrate();
text(bb.age,bb.pos.x,bb.pos.y);
}
假设 ballList 中有 2 个球都是 3 岁,第一个循环获取 ball[0] 然后将其从列表中删除,我将递增并且循环将立即退出,因为 ballList.size() 是现在 1. 所以不是到达 4 岁的球消失了,而是随后的球消失了。