¿Cómo copio una matriz bidimensional de cadenas?

Estoy trabajando con un progtwig que utiliza matrices bidimensionales de cadenas (para empezar, probablemente no sea tan inteligente, pero eh), y me gustaría escribir una función que tome una de estas matrices (digamos matriz1), hace una copia independiente, y la devuelve (digamos array2). Sin embargo, cuando luego cambio un valor en array2, parece reflejarse en array1.

Mi función actualmente es algo como esto:

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

Declaro una nueva matriz de cadenas y luego la itero, copiando cada valor individualmente. Cuando eso no funcionó, incluso intenté declarar explícitamente una nueva cadena de cada cadena antigua y colocarla en la matriz.

¿Alguien puede decirme a dónde me voy mal?

Su método parece que debería funcionar, aunque pasar n como parámetro lo hace quebradizo, sería mejor utilizar el campo de longitud de la matriz de entrada, e incluso podría manejar matrices irregulares de esa manera.

No es necesario hacer una copia del contenido, ya que las cadenas no se pueden cambiar, lo que lleva a la pregunta principal: ¿Qué tipo de cambios está haciendo que parecen reflejarse en la copia? Muéstranos el código que hace esto.

No estoy seguro de para qué sirve el parámetro n , pero si necesitara una función así, usaría algo como esto:

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

No es necesario crear una copia de la String , porque son inmutables. Como señaló Michael en los comentarios, el constructor String(String) podría ser útil si la cadena original se creó como una subcadena de una cadena muy grande. Otro uso es cuando utiliza objetos String como lockings (no recomendado), y desea una instancia privada para evitar interlockings.

Además, su comprobación para ver si un elemento es nulo antes de la asignación no es necesaria; Si tiene la configuración de sus bucles correctamente, se garantiza que el elemento es nulo. (Y si no lo es, ¿qué hay de malo en sobrescribirlo?)

Echa un vistazo a System.arraycopy . De esa manera puedes deshacerte del bucle interno.

Tal vez Arrays.copyOf sería de alguna utilidad?

Intenté con tu código: obtuve la excepción java.lang.ArrayIndexOutOfBoundsException

Está funcionando para mí, por favor intente esto:

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

Eche un vistazo a esta pregunta. ¿Se pasa Java por referencia? Puede ser un poco confuso cómo Java pasa los objetos, pero esto explicaría por qué hacer un cambio en una matriz también lo hace en su otra matriz.

Su uso del parámetro ‘n’, como se indicó anteriormente, es redundante, pero también es defectuoso por su código con n + 1? Su código producirá una ArrayIndexoutOfBoundsException si ejecuta algo como:

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

¿Cuál presumiblemente es cómo pretendes que sea invocado?

También limita su función a “matrices” cuadradas de cadenas. Pero en cuanto al problema que mencionaste, no veo ninguna razón para que el progtwig se comporte de esa manera … incluso lo ejecuté usando la llamada anterior (pero con n = 1 ???) y luego cambié

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

y m1 no se vio afectado como se esperaba. Incluso reemplazando la línea de código más interna para:

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

no cambia esto, ya que el comstackdor lo reescribe a lo que tenías originalmente. De hecho, gran parte de la syntax de String es simplemente azúcar sintáctica para StringBuffers (como concatenación y asignación). por ejemplo, el comstackdor reescribirá

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

a

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

Es por eso que tiene mucha concatenación de cadenas dentro de los bucles que pueden realizar muy mal.

Tampoco entiendo por qué está teniendo el problema que citó.

Y como no está modificando el parámetro ‘matriz’, ‘Pasar por referencia’ no tiene nada que ver con eso.