Java:与ArrayList循环类型相同的新实例停止循环
以下代码中的循环在第一个元素之后停止:Java:与ArrayList循环类型相同的新实例停止循环,java,arraylist,instantiation,Java,Arraylist,Instantiation,以下代码中的循环在第一个元素之后停止: public ArrayList<Position> moveOptions(Player p, Die d) { // Init array ArrayList<Position> options = new ArrayList<>(); Helper.m("Option size: " + options.size()); // Get play
public ArrayList<Position> moveOptions(Player p, Die d)
{
// Init array
ArrayList<Position> options = new ArrayList<>();
Helper.m("Option size: " + options.size());
// Get player's pin positions (current)
ArrayList<Position> pos = p.getPinPositions();
Helper.m("p.getPinPositions() size: " + pos.size());
int i = 0;
for (Position ps : p.getPinPositions()) {
Helper.m("I am in the loop");
// Get the pin in this position
Pin pin = ps.getPin();
// Get next field according to the die
Helper.m("The size of pos before 'next' call:" + pos.size());
Field next = ps.getPin().getNextFieldByDie(d);
Helper.m("The size of pos after 'next' call:" + pos.size());
// If the die value doesn't exceed the board size
if(next != null)
{
Helper.m("next is not null");
Helper.m("The size of pos before constructor call:" + pos.size());
Position possible = new Position(next, ps.getPin());
Helper.m("The size of pos after constructor call:" + pos.size());
options.add(possible);
}
Helper.m("The size of 'options' is now " + options.size());
i++;
}
Helper.m("I: " + i);
Helper.m("The final size of 'options' is " + options.size());
Helper.m("The final size of 'pos' is " + pos.size());
return options;
}
即使我在那里放了一个“continue”,或者在循环外部创建了一个新的位置空实例,循环也不会继续。有什么建议吗
输出如下:
Option size: 0
p.getPinPositions() size: 4
I am in the loop
The size of pos before 'next' call:4
The size of pos after 'next' call:1
next is not null
The size of pos before constructor call:1
The size of pos after constructor call:1
The size of 'options' is now 1
I: 1
The final size of 'options' is 1
The final size of 'pos' is 1
职位类别:
/**
* Keep pin positions in object
*/
public class Position {
// Field object
private Field field;
// Pin Object
private Pin pin;
public Position(){};
/**
* Constructor
* @param f Field object
* @param p Pin Object
*/
public Position(Field f, Pin p)
{
this.setFeild(f);
this.setPin(p);
}
/**
* Field setter
* @param f
*/
public final void setFeild(Field f)
{
this.field = f;
}
/**
* Field getter
* @return
*/
public Field getField()
{
return this.field;
}
/**
* Pin setter
* @param p
*/
public final void setPin(Pin p)
{
this.pin = p;
}
/**
* Pin getter
* @return
*/
public Pin getPin()
{
return this.pin;
}
}
谢谢大家! 此问题是由
getCurrentField()
方法中的Pin
类引起的,当您从循环中调用getNextFieldByDie(Die Die)
时,会调用该方法。问题是您正在从迭代器中删除与当前pin不等效的项。此操作不仅生成一个包含您感兴趣的元素的ArrayList
,它实际上还修改了备份存储,您的代码中的备份存储位于GameManager
类中
public Field getCurrentField()
{
ArrayList<Position> positions = this.getManager().getPinPositions();
for (Iterator<Position> it=positions.iterator(); it.hasNext();) {
if (!it.next().getPin().equals(this))
it.remove();
}
if(positions.size() > 0)
return positions.get(0).getField();
else
return null;
}
我还想指出,您在发布的代码库中的多个位置都出现了相同的模式,所有这些模式都可能导致类似的问题,并且很可能会被切换
碰巧您使用了only方法来修改列表,同时在该列表上迭代,不会抛出
ConcurrentModificationException
,从而更难检测到原始列表中发生了更改。您是如何得出位置可能=新的结论的位置(下一步,ps.getPin())代码>行是问题所在?可能无法解决您的问题,但您可以将对ps.getPin()
的调用更改为pin
行中的Position-mable=new-Position(下一步,ps.getPin())代码>假设您不调用任何其他内容,则会对您关心的值进行更改。在Position
类中是否有类似这样的构造函数:public Position(字段f,Pin p){…}
对不起,我不相信您;)你能发布一篇我们可以复制的文章吗?@Sam请查看这个存储库:它解决了这个问题。我使用“迭代器”时并不知道它的全部情况。谢谢你抽出时间!我会到处修理这些。
public Field getCurrentField()
{
ArrayList<Position> positions = this.getManager().getPinPositions();
for (Iterator<Position> it=positions.iterator(); it.hasNext();) {
if (!it.next().getPin().equals(this))
it.remove();
}
if(positions.size() > 0)
return positions.get(0).getField();
else
return null;
}
public Field getCurrentField()
{
ArrayList<Position> positions = this.getManager().getPinPositions();
//Just create a new list
ArrayList<Position> matchedPositions = new ArrayList<Position>();
//Use the for-each syntax to iterate over the iterator
for (Position position : positions) {
//switch the logic and add to the new list
if (position.getPin().equals(this))
matchedPositions.add(position);
}
if(matchedPositions.size() > 0)
return matchedPositions.get(0).getField();
else
return null;
}