2008-11-19 26 views
9

Tengo algunos datos almacenados como ArrayList. Y cuando quiero hacer una copia de seguridad de estos datos, java limita dos objetos para siempre. Lo que significa que cuando cambio valores en los datos ArrayList, estos cambios vienen a la copia de seguridad. Traté de copiar los valores de los datos por separado para hacer una copia de seguridad en el ciclo, intenté usar el método data.clone() - nada ayuda.¿Cómo hacer una copia de seguridad de ArrayList en Java?

+0

¿Qué quiere decir con "copia de seguridad"? ¿Quiere decir que quiere crear otra ArrayList que contenga lo que está en la ArrayList actual? –

Respuesta

12

Creo que necesita .clone() los objetos individuales. La clonación del ArrayList no es "profunda"; solo clonará las referencias al objeto.

-3

Puede escribir un objeto que ajuste dos ArrayLists. Todo lo escribe para que agregue, elimine y modifique datos en ambos al mismo tiempo.

1

Suena (si interpreto correctamente tu pregunta, es un poco difícil) como si no estuvieras copiando los datos a los que te refieres en tu ArrayList a tu copia de seguridad; estás copiando la referencia.

Es difícil decir exactamente cómo resolver su problema sin saber cuál es su tipo de datos que está almacenando/respaldando, pero solo asegúrese de copiar los elementos de los datos contenidos en ArrayList. Eso significaría, entre otras cosas, hacer cosas como realizar un clon() en los elementos de la lista, pero no en ArrayList (porque eso creará una nueva lista clonada con copias de las referencias a los mismos objetos).

4

Todos estos procesos hacen copias superficiales. Si está cambiando propiedades de objetos en la matriz, las dos matrices tienen referencias a la misma instancia.

List org = new java.util.ArrayList(); 
org.add(instance) 
org.get(0).setValue("org val"); 
List copy = new java.util.ArrayList(org); 
org.get(0).setValue("new val"); 

copy.get(0).getValue() regresará "new val" así porque org.get(0) y copy.get(0) volver exactamente la misma instancia. Debe realizar una copia profunda como esta:

List copy = new java.util.ArrayList(); 
for(Instance obj : org) { 
    copy.add(new Instance(obj)); // call to copy constructor 
} 
+0

Gracias! Tenía la misma Pregunta que el OP, y tu respondiste perfectamente. DeepCopy vs Shallow Copy! y más importante aún, ¡cómo hacer una copia profunda! –

15

Su pregunta no es muy clara. Si clonas() una lista de arreglos, la copia no se modificará si cambias los contenidos del original (es decir, si agregas o quitas elementos) pero es una "copia superficial", por lo que si cambias los objetos reales en el original, lo harán también se cambiará en el clon.

Si desea hacer una "copia profunda", de modo que los cambios en los objetos reales no afecten las copias de seguridad de los mismos en el clon, entonces necesita crear una nueva ArrayList y luego pasar por la original y para cada elemento, clonarlo en el nuevo. Al igual que en

ArrayList backup = new ArrayList(); 
for (Object obj : data) 
    backup.add(obj.clone()); 
8

Asumo data es el nombre de la ArrayList que quería hacer copias de seguridad. Si es así, debe saber que clone no es profundo - solo crea una copia del objeto al que se invoca, que en este caso es la lista. Si fuera un clon profundo, llenaría la nueva lista con clones de los objetos en él.

Dado que no es profundo, si cambia los objetos que contiene la lista, la lista de respaldo también mostrará esos cambios, ya que contiene los mismos objetos. La única vez que no verá cambios en la copia de seguridad después de cambiar la lista "actual" es cuando agrega o elimina objetos de la lista actual.

Algunas clases pueden anular clone para ser profundas, pero no todas. En general, no es algo en lo que pueda confiar. Al crear una copia de respaldo de las colecciones de Java, recuerde clonar también los objetos contenidos, o tratar solo con colecciones de objetos inmutables.

0

En cuanto al problema de la clonación, una vez que resolví esto serializando toda la colección en una cadena y luego serializándola en un nuevo objeto. Esto te obliga a hacer todos tus objetos serializables y tomarlos cuando dos objetos realmente quieren hacer referencia a un solo tercer objeto, pero puede ser un buen equilibrio entre simplicidad y utilidad.

En realidad, no he probado esto, pero que probablemente podría utilizar un tubo para serializar dentro y fuera al mismo tiempo exacto para que no se está almacenando 3 copias en la memoria (si se trata de una enorme colección)

-1

No lo he intentado todavía, pero creo que Collections.copy lo hará.

[EDIT] Ahora, he intentado:

static String GetRandomString(int length) 
{ 
    UUID uuid = UUID.randomUUID(); 
    return uuid.toString().substring(0, length); 
} 

public static void main(String[] args) 
{ 
    ArrayList<String> al = new ArrayList<String>(20); 
    for (int i = 0; i < 10; i++) 
    { 
    al.add(GetRandomString(7)); 
    } 
    ArrayList<String> cloneArray = new ArrayList<String>(al); 
    Collections.copy(cloneArray, al); 
    System.out.println(al); 
    System.out.println(cloneArray); 
    for (int i = 9; i >= 0; i -= 2) 
    { 
    al.remove(i); 
    } 
    System.out.println(al); 
    System.out.println(cloneArray); 
} 
+0

Esto creo que realmente no muestra la copia profunda ya que la operación de agregar/eliminar no alterará la lista original. Intenté con su mismo código pero reemplacé el contenido de la lista con una clase personalizada y alteré el contenido (en lugar de eliminarlos), luego la lista copiada también se modificó. – Nrj

+0

@Nrj: ah, tienes razón, las listas son independientes pero aún apuntan a (referencia) los mismos objetos, por lo que sigue siendo una copia superficial. Mi mal (hey, hace dos años, ¡no era muy bueno en Java! :-)) – PhiLho

3

depende de lo que necesita. copia superficial (elementos de la lista son referencias a los mismos que en el original):

ArrayList backup = new ArrayList(mylist.size()); 
backup.addAll(mylist); 

copia profunda (artículos son copias también):

ArrayList backup = new ArrayList(mylist.size()); 
for(Object o : mylist) { 
    backup.add(o.clone()); 
} 
Cuestiones relacionadas