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;
}