我正在使用一个使用二维数组字符串的程序(可能不是那么聪明,但是呃),我想编写一个函数来接受其中一个数组(比如说array1) ),制作一个独立的副本,然后返回它(比如说array2)。但是,当我在array2中更改一个值时,它似乎反映在array1中。
我的功能目前看起来像这样:
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;
}
我声明了一个新的字符串数组,然后遍历它,分别复制每个值。当这不起作用时,我甚至尝试从每个旧字符串中明确声明一个新字符串并将其放入数组中。
谁能告诉我哪里出错?
答案 0 :(得分:5)
我不确定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
的副本,因为它们是不可变的。正如Michael在评论中指出的那样,如果原始字符串是作为某个非常大的字符串的子字符串创建的,String(String)
构造函数可能会有用。另一个用途是当您使用String
个对象作为锁(不推荐),并希望私有实例避免死锁。
另外,在分配之前检查元素是否为空是不必要的;如果您正确设置了循环,则该元素保证为null。 (如果不是,覆盖它有什么害处呢?)
答案 1 :(得分:3)
看看System.arraycopy。这样你就可以摆脱内循环。
答案 2 :(得分:3)
你的方法看起来应该可以工作,虽然传入n作为参数会使它变脆,使用输入数组的长度字段会更好,你甚至可以用这种方式处理锯齿状数组。
制作内容的副本是没有必要的,因为字符串无法更改 - 这导致了一个主要问题:您所做的哪些更改似乎会反映在副本中?向我们展示执行此操作的代码。
答案 3 :(得分:1)
也许Arrays.copyOf会有用吗?
答案 4 :(得分:1)
我尝试使用你的代码:得到例外 java.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;
}
答案 5 :(得分:0)
看看这个问题Is Java pass by reference? Java传递对象有点令人困惑,但这可以解释为什么对一个数组进行更改也会改变你的其他数组。
答案 6 :(得分:0)
如上所述,你使用'n'参数是多余的,但你的代码也会因n + 1而有缺陷?如果运行类似:
,您的代码将产生ArrayIndexoutOfBoundsException
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'与它无关。