如何克隆Java中的多维数组? [英] How to clone a multidimensional array in java?
问题描述
编辑2:下面是基于DuffyMo的响应code片段,展示了如何绕过克隆使用System.arraycopy多维数组的限制。
进口java.util.Arrays中;公共类Randar {
公共静态INT [] [] arrayMaster = {{6,1},{10,1},{1,1}};
私有静态诠释[] [] = arrayChanges新INT [arrayMaster.length] [2];公共Randar(){}
公共静态无效的主要(字串[] args){
arrayChanges [0] [0] = 0;
resetArrays(arrayChanges,arrayMaster);
arrayChanges [0] [0] = 0; System.out.format(arrayMaster:%S,arrayChanges:%S,Arrays.deepToString(arrayMaster),Arrays.deepToString(arrayChanges));
}
公共静态无效resetArrays(INT [] [] arrayChanges,INT [] [] arrayMaster){
对于(int类型的= 0; A< arrayMaster.length; A ++){
System.arraycopy(arrayMaster [α],0,arrayChanges [α],0,arrayMaster [α]。长度);
}
// arrayChanges = arrayMaster.clone();作为将无法正常工作
}
}
【原题】
什么是简单的方式(完全)克隆在Java中的多维数组?该程序说明了我的问题。
进口java.util.Arrays中;公共类Randar {
公共静态INT [] [] arrayMaster = {{6,1},{10,1},{1,1}};
静态私人INT [] [] = arrayChanges arrayMaster;公共静态无效的主要(字串[] args){
arrayChanges [0] [0] = 0;
resetArrays(); System.out.format(arrayMaster:%S,arrayChanges:%S,Arrays.deepToString(arrayMaster),Arrays.deepToString(arrayChanges));
}
公共静态无效resetArrays(){
arrayChanges = arrayMaster.clone();
}}
在运行上述code,arrayMaster的变化以及arrayChanges,违背了我的意图。以为我能克隆arrayMaster的每个一维数组成员,我试图解决该问题与此:
的for(int ITER = 0;&ITER LT; arrayMaster.length; ITER ++){
arrayChanges [ITER] = arrayMaster [国际热核实验堆] .clone();
}
但是当我运行code,让出于某种原因一个NullPointerException异常。正在写,通过阵列我唯一的选择?
的各个整数循环的方法感谢。
编辑1:这并不任解决问题
进口java.util.Arrays中;公共类Randar {
公众诠释[] [] arrayMaster = {{6,1},{10,1},{1,1}};
私人INT [] [] = arrayChanges arrayMaster.clone();公共Randar(){}
公共静态无效的主要(字串[] args){
Randar Randar1 =新Randar();
Randar1.arrayChanges [0] [0] = 0;
resetArrays(Randar1.arrayChanges,Randar1.arrayMaster);
Randar1.arrayChanges [0] [0] = 0; System.out.format(arrayMaster:%S,arrayChanges:%S,Arrays.deepToString(Randar1.arrayMaster),Arrays.deepToString(Randar1.arrayChanges));
}
公共静态无效resetArrays(INT [] [] arrayChanges,INT [] [] arrayMaster){
/ *为(int类型的= 0; A< arrayMaster.length; A ++){
System.arraycopy(arrayMaster [α] .clone(),0,arrayChanges [α],0,arrayMaster [α]。长度);
} * /
arrayChanges = arrayMaster.clone();
}
}
在运行上述code,arrayMaster的变化以及arrayChanges,违背了我的意图。
块引用>行
静态私人INT [] [] = arrayChanges arrayMaster;
是罪魁祸首。此行让
arrayChanges
和arrayMaster
指向同一个对象,所以更改或者当你访问一个可见从任一对象。编辑:每当你克隆多维数组的一个维度,会发生什么
作为<一个href=\"http://blogs.msdn.com/b/ericlippert/archive/2008/09/22/arrays-considered-somewhat-harmful.aspx\">Eric利珀特解释,数组是概念上的变量列表。如果你只是分配其他变量指向同一个数组一拉
静态私人INT [] [] = arrayChanges arrayMaster;
,你有没有改变的变量集在所有。您还没有创建任何新的变量,除了arrayChanges
,所以你没有从操作系统/ JVM得到更多的内存,让你做出任何更改arrayMaster
用于arrayChanges
,反之亦然。现在让我们看一下二维数组。在Java中,一个二维数组是恰好有这些变量中的每一个是指一个一维数组的属性的变量的列表。所以,当你克隆一个二维数组,您创建的变量一个新的列表,在旧的变量指向同一个地方每一个指向。所以,你必须在获得了一点点,你可以放心地写
arrayChanges [0] =新的INT [10]
不影响arrayMaster
,但只要你开始引用arrayChanges [ I] [J]
你仍然引用相同的第二级阵列的arrayMaster
引用。你真的想以深拷贝整数的二维数组是什么公共静态INT [] [] deepCopyIntMatrix(INT [] []输入){
如果(输入== NULL)
返回null;
INT [] []结果=新INT [input.length] [];
对于(INT R = 0;为r input.length; R ++){
结果[R] =输入[R] .clone();
}
返回结果;
}对于那些谁可以看看这个答案在未来:是的,这是更好的替代
INT
与T
在这里,使通用的方法,但是用于此目的的更具体的深拷贝的方法是简单的解释好。Edit 2: Below is a code snippet based on DuffyMo's response that illustrates how to get around the limitations of cloning for multidimensional arrays using System.arraycopy.
import java.util.Arrays; public class Randar { public static int[][] arrayMaster = {{6,1}, {10,1}, {1,1}}; private static int[][] arrayChanges = new int[arrayMaster.length][2]; public Randar () { } public static void main(String[] args) { arrayChanges[0][0] = 0; resetArrays(arrayChanges, arrayMaster); arrayChanges[0][0] = 0; System.out.format("arrayMaster: %s, arrayChanges: %s", Arrays.deepToString(arrayMaster), Arrays.deepToString(arrayChanges)); } public static void resetArrays(int[][] arrayChanges, int[][] arrayMaster) { for (int a=0; a< arrayMaster.length; a++) { System.arraycopy(arrayMaster[a], 0, arrayChanges[a], 0, arrayMaster[a].length); } // arrayChanges = arrayMaster.clone(); will NOT work as expected } }
[ORIGINAL QUESTION] What's a simple way to (fully) clone a multidimensional array in java? This program illustrates my problem.
import java.util.Arrays; public class Randar { public static int[][] arrayMaster = {{6,1}, {10,1}, {1,1}}; static private int[][] arrayChanges = arrayMaster; public static void main(String[] args) { arrayChanges[0][0] = 0; resetArrays(); System.out.format("arrayMaster: %s, arrayChanges: %s",Arrays.deepToString(arrayMaster), Arrays.deepToString(arrayChanges)); } public static void resetArrays() { arrayChanges = arrayMaster.clone(); } }
When the above code is run, arrayMaster changes as well as arrayChanges, contrary to my intentions. Thinking that I could clone each single dimensional array member of arrayMaster, I tried to get around the problem with this:
for (int iter = 0; iter < arrayMaster.length; iter++) { arrayChanges[iter] = arrayMaster[iter].clone(); }
but when I run the code that gives a NullPointerException for some reason. Is writing a method that loops through the individual integer values of the arrays my only option?
Thanks.
EDIT 1: This doesn't fix the problem either.
import java.util.Arrays; public class Randar { public int[][] arrayMaster = {{6,1}, {10,1}, {1,1}}; private int[][] arrayChanges = arrayMaster.clone(); public Randar () { } public static void main(String[] args) { Randar Randar1 = new Randar(); Randar1.arrayChanges[0][0] = 0; resetArrays(Randar1.arrayChanges, Randar1.arrayMaster); Randar1.arrayChanges[0][0] = 0; System.out.format("arrayMaster: %s, arrayChanges: %s", Arrays.deepToString(Randar1.arrayMaster), Arrays.deepToString(Randar1.arrayChanges)); } public static void resetArrays(int[][] arrayChanges, int[][] arrayMaster) { /*for (int a=0; a< arrayMaster.length; a++) { System.arraycopy(arrayMaster[a].clone(), 0, arrayChanges[a], 0, arrayMaster[a].length); } */ arrayChanges = arrayMaster.clone(); } }
解决方案When the above code is run, arrayMaster changes as well as arrayChanges, contrary to my intentions.
The line
static private int[][] arrayChanges = arrayMaster;
is the culprit. This line makes
arrayChanges
andarrayMaster
point to the same object, so a change to either one is visible when you access the object from either.EDIT: What happens whenever you clone one dimension of a multidimensional array
As Eric Lippert explains, an array is conceptually a list of variables. If you just assign another variable to point to the same array a la
static private int[][] arrayChanges = arrayMaster;
, you haven't changed the set of variables at all. You haven't created any new variables except forarrayChanges
, so you haven't gotten more memory from the operating system/JVM, so any change you make toarrayMaster
is applied toarrayChanges
and vice versa.Now let's look at a two-dimensional array. In Java, a two-dimensional array is a list of variables that happens to have the property that each one of these variables refers to a one-dimensional array. So, whenever you clone a two-dimensional array, you create a new list of variables, each pointing in the same place that the old variables pointed in. So, you have gained a little in that you can safely write
arrayChanges[0] = new int[10]
without affectingarrayMaster
, but as soon as you start referencingarrayChanges[i][j]
you are still referencing the same second-level arrays thatarrayMaster
references. What you really want in order to deep-copy a two-dimensional array of ints ispublic static int[][] deepCopyIntMatrix(int[][] input) { if (input == null) return null; int[][] result = new int[input.length][]; for (int r = 0; r < input.length; r++) { result[r] = input[r].clone(); } return result; }
To those who may look at this answer in the future: yes, it is better replace
int
withT
here and make the method generic, but for this purpose a more concrete deep copy method is simpler to explain well.这篇关于如何克隆Java中的多维数组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!