gpt4 book ai didi

java - 如何循环在循环期间发生变化的 ArrayList

转载 作者:行者123 更新时间:2023-11-29 03:09:03 25 4
gpt4 key购买 nike

我有一个 Sprite 类:

public class Sprite {
public static ArrayList<Sprite> sprites = null;
private Texture texture = null;

public Sprite(Texture texture) {
sprites.add(this);
this.texture = texture;
}

public void render(SpriteBatch batch) {
batch.draw(texture);
}

public void dispose() {
sprites.remove(this);
}
}

在我创建任何 Sprite 之前,我确保 Sprite 类具有对将要渲染的 Sprite 池的引用:

public class Main extends ApplicationAdapter {
private static ArrayList<Sprite> sprites = new ArrayList<Sprite>();

public Main() {
Sprite.sprites = sprites;

new Sprite("texture.png");
}

@Override
public void render(SpriteBatch batch) {
for (int i = 0; i < sprites.size(); i++)
sprites.get(i).render(batch);
}
}

所以现在当我创建一个新的 sprite 时,它​​会自动呈现,而无需我手动将它添加到 ArrayList 中。

问题是 sprite 可以在 for 循环运行期间被释放,因此某些 sprite 不会在该特定帧渲染。

我不想向后循环遍历项目,例如:

for (int i = sprites.size() - 1; i >= 0; i--)
sprites.get(i).render(batch);

因为这会使我的 sprite 乱序(应该在顶部的 sprite 将被覆盖)。

到目前为止,我唯一的解决方案是使用另一个 ArrayList 来跟踪要处理的对象,例如:

public class Sprite {
public static ArrayList<Sprite> sprites = null, garbage = null;

//everything else the same

public void dispose() {
garbage.add(this);
}
}

然后在渲染过程中,我首先从 Sprite 中移除所有垃圾,然后渲染 Sprite :

for (int i = 0; i < garbage.size(); i++)
sprites.remove(garbage.get(i));
garbage.clear();

for (int i = 0; i < sprites.size(); i++)
sprites.get(i).render(batch);

这个方法可行,但我感觉效率不高。 (有两个数组列表?然后做两个 for 循环?)

有什么方法可以循环遍历 Sprites 而不会在处置 Sprite 时跳过 Sprite?我不想向后循环 Sprites,因为它会打乱顺序。

我现在已经使用同步列表对此进行了测试,但我无法使其正常工作。

Testable code , (与 java.util.ConcurrentModificationException)

import java.util.*;

class Ideone {

public static class Sprite {
public static List<Sprite> sprites = null;
public int age = 0;

public Sprite() {
synchronized(sprites) {
sprites.add(this);
}
}

public void render() {
age++;
if (age > 30)
dispose();
}

public void dispose() {
synchronized(sprites) {
sprites.remove(this);
}
}
}

private static List<Sprite> sprites = Collections.synchronizedList(new ArrayList<Sprite>());

public static void main(String[] args) {
Sprite.sprites = sprites;

new Sprite();
new Sprite();

for (int i = 0; i < 60; i++)
render();

}

public static void render() {
synchronized(sprites) {
Iterator<Sprite> iterator = sprites.iterator();
while (iterator.hasNext())
iterator.next().render();
}
}
}

最佳答案

首先,如果从多个线程访问sprites 列表,您需要同步访问它或使用线程安全数据结构(例如 CopyOnWriteArrayList 或 CopyOnWriteArraySet)。

在这种情况下,

Sprite.dispose 可以直接从 sprites 中移除自己。

关于java - 如何循环在循环期间发生变化的 ArrayList,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30488297/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com