如何复制二维字符串数组?

我正在使用一个使用二维数组字符串的程序(可能不是那么聪明,但是呃),我想编写一个函数来接受其中一个数组(比如说array1),make一个独立的副本,并返回它(比如说array2)。 但是,当我在array2中更改一个值时,它似乎反映在array1中。

我的function目前看起来像这样:

public static String[][] copy(String[][] matrix, int n) { String[][] out = new String[n+1][n+1]; for (int i = 0; i < n+1; i++) for (int j = 0; j < n+1; j++) { if(matrix[i][j] != null) { String cp = new String(matrix[i][j]); out[i][j] = cp; } } return out; } 

我声明了一个新的字符串数组,然后遍历它,分别复制每个值。 当这不起作用时,我甚至试图从每个旧字符串中明确声明一个新字符串并将其放入数组中。

谁能告诉我哪里出错了?

你的方法看起来应该可以工作,虽然传入n作为参数会使它变脆,使用输入数组的长度字段会更好,你甚至可以用这种方式处理锯齿状数组。

制作内容的副本是没有必要的,因为字符串无法更改 – 这导致了一个主要问题:您所做的哪些更改似乎反映在副本中? 向我们展示执行此操作的代码。

我不确定n参数是什么,但如果我需要这样的函数,我会使用这样的东西:

 public static String[][] copy(String[][] matrix) { String[][] copy = new String[matrix.length]; for (int idx = 0; idx < matrix.length; ++idx) copy[idx] = matrix[idx].clone(); return copy; } 

您不需要创建String的副本,因为它们是不可变的。 正如迈克尔在评论中指出的那样,如果原始字符串是作为某个非常大的字符串的子字符串创建的,那么String(String)构造函数可能会很有用。 另一个用途是当您使用String对象作为锁(不推荐)时,并希望私有实例避免死锁。

另外,在分配之前检查元素是否为空是不必要的; 如果您正确设置了循环,则该元素保证为null。 (如果不是,覆盖它有什么害处呢?)

看看System.arraycopy 。 这样你就可以摆脱内循环。

也许Arrays.copyOf会有用吗?

我尝试使用你的代码:得到exceptionjava.lang.ArrayIndexOutOfBoundsException

这对我有用,请尝试这样:

  public static String[][] copy(String[][] matrix, int n) { String[][] out = new String[n][n]; for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) { if(matrix[i][j] != null) { String cp = new String(matrix[i][j]); out[i][j] = cp; } } return out; } 

看一下这个问题Java是通过引用传递的吗? Java传递对象可能有点令人困惑,但这可以解释为什么对一个数组进行更改也会对其他数组进行更改。

如上所述,你使用’n’参数是多余的,但你的代码也会因n + 1而有缺陷? 如果运行如下代码,您的代码将产生ArrayIndexoutOfBoundsException:

String [][] m1 = { {"A", "B"}, {"C", "D" } }; String [][] m2 = copy(m1, 2);
String [][] m1 = { {"A", "B"}, {"C", "D" } }; String [][] m2 = copy(m1, 2); 

大概是你打算如何调用它?

它还将你的函数限制为字符串的矩阵’矩阵’。 但至于你引用的问题,我认为没有理由为什么程序应该这样做…我甚至使用上面的调用运行它(但是n = 1 ???)然后改变了

 m2[0][1] = "X"; 

并且m1没有像预期的那样受到影响。 甚至将最里面的代码行替换为:

 out[i][j] = matrix[i][j]; 

不会改变这一点,因为编译器会将其重写为您最初拥有的内容。 事实上,很多String sytax只是StringBuffers的语法糖(例如连接和赋值)。 例如,编译器将重写

 String s = "Hello "; s += "World"; // Makes it appear that String is builtin type! 

 String s = new String("Hello "); s = new StringBuffer(s).append("World").toString(); 

这就是为什么你在循环中有很多字符串连接它们可以执行得非常糟糕。

我不明白你为什么会遇到你引用的问题。

由于您没有修改参数’matrix’,’Pass By Reference’与它无关。