You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java循环中向ArrayList添加Matrices对象仅存最后迭代结果的问题

问题原因

Java里数组属于引用类型,你每次调用m.setM(A)时,并没有复制数组A的内容,只是把A的内存地址(引用)传给了Matrices对象的M属性。所有添加到ArrayList的Matrices对象,它们的M都指向同一个数组实例。后续循环修改A的元素时,所有引用指向的都是同一个数组,所以最后所有Matrices里的数组都会显示最后一次迭代的结果。

解决方案

要保存每次迭代的不同数组,必须在添加到ArrayList前创建当前数组的独立副本,把副本存入Matrices对象,这样每个对象持有互不影响的数组。

方案1:修改Matrices类自动处理复制

在setM方法里自动复制传入的数组,调用方无需额外操作:

public class Matrices {
    private int M[][];
    
    public int[][] getM() {
        // 可选:返回副本,防止外部修改内部数组
        return copyMatrix(M);
    }

    public void setM(int[][] M) {
        // 复制传入的数组,而非直接保存引用
        this.M = copyMatrix(M);
    }
    
    // 工具方法:复制二维int数组
    private int[][] copyMatrix(int[][] original) {
        if (original == null) return null;
        int[][] copy = new int[original.length][];
        for (int i = 0; i < original.length; i++) {
            copy[i] = original[i].clone();
        }
        return copy;
    }
}

方案2:在主代码中手动复制数组

如果不想修改Matrices类,可在添加前手动生成数组副本:

ArrayList<Matrices> matrices=new ArrayList<>();
int[][] A=panel.CreaMatriz();
//Inicio Floyd 
for (int k = 0; k < nodos.size(); k++) {
    // 复制当前A的副本
    int[][] currentCopy = new int[A.length][];
    for (int i = 0; i < A.length; i++) {
        currentCopy[i] = A[i].clone();
    }
    // 将副本存入Matrices并添加到集合
    Matrices m=new Matrices();
    m.setM(currentCopy);
    matrices.add(m);
    
    // 修改原数组A,不会影响已保存的副本
    for (int i = 0; i < nodos.size(); i++) {
        for (int j = 0; j < nodos.size(); j++) {
            if (A[i][k]+A[k][j]<A[i][j]){
                A[i][j]=A[i][k]+A[k][j];   
            }
        }
     }
}
效果验证

修改后,ArrayList中的每个Matrices对象都会持有当前迭代时刻的数组副本,后续修改原数组A不会影响这些副本,就能得到你期望的每次迭代不同的数组输出。

内容的提问来源于stack exchange,提问作者FenixDynamoYT

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 14:35:23