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
相关产品推荐
相关产品推荐

