从ArrayList元素复制数组

3

我正在使用Swing构建一个基于Java的游戏,它本质上是一个JButton的网格。

我有一个名为Cell的对象,它是一个自定义的JButton,具有用于存储对象的附加参数。游戏网格由Cell[][]表示。

我有一个类型为Cell[][]的数组列表,以便在每次移动后存储游戏网格的状态。如果我想撤消移动,则需要将ArrayList的最后一个元素复制到游戏网格中,以便在UI上显示。

我的游戏网格是panelHolder,我的数组列表是moveHolder

到目前为止,我尝试过Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));,但由于"参数不适用于类型Cell[][]"而无法编译。

我还尝试过System.arraycopy(moveHolder.get(moveHolder.size()-1), 0, panelHolder, 0, panelHolder.length);,但会抛出越界异常。起初我认为这是由于moveHolder.size()-1,但即使只有moveHolder.size()也会出现同样的问题。

我在StackOverflow和其他地方找到了许多相关问题,其中两种方法都被展示了出来,但我似乎无法使其正常工作。我是否忽略了什么更明显的问题?下面是完整的类方法:

 public class UndoClass implements MoveCommand{

    public ArrayList<Cell[][]> moveHolder = new ArrayList<Cell[][]>();

    public Cell[][] execute(Cell[][] panelHolder) {
        if (moveHolder.size() > 0){
            Collections.copy(panelHolder, moveHolder.get(moveHolder.size()));       
            if (moveHolder.size() > 0){
                moveHolder.remove(moveHolder.size());
            }
        }
        System.out.println("Move Undone. Undos available:" + moveHolder.size());
        return panelHolder;
    }
    public void addMove(Cell[][] panelHolder){
        moveHolder.add(panelHolder);
    }

    public ArrayList<Cell[][]> getMoves(){  
        return moveHolder;
    }
}

单元格类

public class Cell extends JButton {

    int co_x = 0;
    int co_y = 0;


    ArrayList<Players> current = new ArrayList <Players>();

}

2
由于panelHolder和moveHolder.get(n)都是数组,因此System.arraycopy是正确的方法。倾倒两个数组的长度以检查它们是否符合您的预期。 - JP Moresmau
@ChetanKinger 编辑添加了 Cell 类。 - jmo
这并不回答你的问题,但我个人建议在这里使用LinkedList而不是ArrayList。 - celticminstrel
2
我认为你的问题在于这是一个数组的数组。这个回答有帮助吗?https://dev59.com/4HI_5IYBdhLWcg3wBuJs/ - celticminstrel
@celticminstrel,这似乎是我想要的。我会看一下并尝试让它工作或将其融入我的问题中。 - jmo
显示剩余4条评论
3个回答

1

我想指出你的execute(...)方法既接受Cell[][]作为参数,也作为返回值。这种方法会强制所有命令都要将输入参数数组复制到返回语句数组中。请注意,如果您不需要保持两者同步,只需使用返回参数即可,您根本不必担心复制:

Cell[][] lastState = moveHolder.get(moveHolder.size()-1);
moveHolder.remove(moveHolder.size()-1);
return lastState;  // Not updating the panelHolder array, just returning

但是现在输入参数和返回值不同步了。相反,您可能希望将该状态封装到一个单独的对象中,以使您的生活更轻松。类似这样(请注意,执行现在返回void):

public ArrayList<GameState> previousStates = new ArrayList<GameState>();

public void execute(GameState currentState) {
    if (previousStates .size() > 0) {
         GameState lastState = previousStates.get(previousStates.size()-1);
         currentState.restoreFrom(lastState);
         previousStates .remove(moveHolder.size()-1);
    }   
 }

祝你游戏好运!

0
尝试使用链表。
    LinkedList<Cell[][]> ll = new LinkedList();
    ll.removeLast();
    panelHolder = ll.clone();

0
if (moveHolder.size() > 0) {
    for (int i = 0; i < panelHolder.length; i++) {
        panelHolder[i] = moveHolder.get(moveHolder.size()-1)[i].clone();   
    }
    moveHolder.remove(moveHolder.size()-1);
}

尝试这个。在复制2D数组时,您需要复制每个内部数组的副本。

@celticminstrel 谢谢,我不知道为什么,但是 Stack Overflow 是我出最多错别字的地方。 - BoDidely
这个代码能够成功拷贝!虽然还没有完全解决我的问题(目前我添加状态的逻辑有些问题),但是它确实满足了我的需求。 - jmo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接