How to copy a two-dimensional array of strings?

I am working with a program that uses two-dimensional array of strings (maybe not so smart, but first, but eh), and I would like to write a function that takes one of these arrays (let's say array1), makes an independent copy and returns it (let's say array2). However, when I then change the value in array2, it seems to be reflected in array1.

My function looks something like this:

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; } 

I declare a new array of strings, and then repeat it, copying each value individually. When this did not work, I even tried to explicitly declare a new line from each old line and put it in an array.

Can someone tell me where I am going wrong?

+4
source share
7 answers

Your method looks as if it should work, although going to n as a parameter makes it fragile, using the input array's length field would be better, and you could even treat jagged arrays that way.

Creating a copy of the content is not required since the lines cannot be changed - which leads to the main question: what changes do you make that seem to be reflected in the copy? Show us the code that does this.

+3
source

I'm not sure why the n parameter is needed, but if I needed such a function, I would use something like this:

 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; } 

You do not need to create a copy of String because they are immutable. As Michael noted in the comments, the String(String) constructor can be useful if the original string was created as a substring of some very large string. Another use is when you use String objects as locks (not recommended) and want a private instance to avoid deadlocks.

In addition, your check to check if the item is null before the destination is not necessary; if you have configured your loops correctly, the element is guaranteed to be zero. (And if it is not, what harm is there in rewriting it?)

+5
source

Take a look at System.arraycopy . This way you can get rid of the inner loop.

+3
source

Maybe Arrays.copyOf will be useful?

+1
source

I tried with your code: got java.lang.ArrayIndexOutOfBoundsException exception

This works for me, please try like this:

  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; } 
+1
source

Take a look at this question. Is Java passed by reference? It may be a bit confusing how Java passes objects, but this explains why making changes to one array also changes your other array.

0
source

Your use of the "n" parameter, as noted above, is redundant, but also corrupted by code with n + 1 ?? Your code will throw an ArrayIndexoutOfBoundsException if you use something like:

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

What, apparently, is how you are going to call it?

It also limits your function to square "matrixes" of strings. But as for the problem you quoted, I see no reason why the program should behave this way ... I even ran it using the above call (but with n = 1 ???), and then changed

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

and m1 did not affect as expected. Even replacing the innermost line of code with:

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

does not change this, since the compiler rewrites it to what you originally had. Actually a lot of String syntax is just the syntactic sugar for StringBuffers (like concatenation and assignment). for example, the compiler will rewrite

 String s = "Hello "; s += "World"; // Makes it appear that String is builtin type! 
for
 String s = new String("Hello "); s = new StringBuffer(s).append("World").toString(); 
This is why you have a lot of string concatenation inside loops that they can do very poorly.

I do not understand why you have a problem that you have indicated.

And since you are not changing the matrix parameter, Pass By Reference has nothing to do with it.

0
source

All Articles