2011-01-04 17 views
18
ArrayList<Integer> a=new ArrayList<Integer>(); 
a.add(5); 
ArrayList<Integer> b=(ArrayList<Integer>)a.clone(); 
a.add(6); 
System.out.println(b.toString()); 

En la pieza de código anterior, creo que clone() hace una copia superficial. Así, b y a debe apuntar a la misma posición de memoria. Sin embargo, cuando lo hago b.toString(), la respuesta es única 5. ¿Por qué se 6 también no se visualiza si clone() hace una copia superficial?clone(): ArrayList.clone() pensé hace una copia superficial

Respuesta

49

copia superficial no significa que apuntan a la misma posición de memoria. Eso sería solo una tarea: List b = a;.

La clonación crea una nueva ejemplo, la celebración de las mismas elementos. Esto significa que tiene 2 listas diferentes, pero sus contenidos son los mismos. Si cambia el estado de un objeto dentro de la primera lista, cambiará en la segunda lista. (Puesto que usted está utilizando un tipo inmutable - Integer - no se puede observar este)

Sin embargo, se debe considerar no usar clone(). Funciona bien con las colecciones, pero en general se considera roto. Utilizar la copia-constructores - new ArrayList(originalList)

+1

así que cuál es la diferencia entre copia profunda y copia superficial – TimeToCodeTheRoad

+1

es correcto decir que la creación de un clon de una lista que contiene los objetos de clase única mutables , es un desperdicio – TimeToCodeTheRoad

+1

@TimeToCodeTheRoad copia superficial funciona igual que Bozho explicó, copias de copias profundas del ArrayList y sus elementos. Para –

5

Si se como tú que pensamos, entonces el clone método sería ser completamente inútil, porque en ese caso, las siguientes líneas se ser equivalente:

ArrayList<Integer> b = (ArrayList<Integer>)a.clone(); 
ArrayList<Integer> b = a; 

la clonación es - como en escenarios del mundo real - un proceso de creación de dos entidades con exactamente las mismas propiedades (en el momento de la operación de clonación).

y como se mencionó Bozho - evitar el concepto de Java clone(). Incluso su autor mencionado, que está roto.

This question and it's answers son muy valiosos y ofrecer un enlace a Josh Bloch propios comentarios sobre su obra ;-)

0

no podemos seleccionar dinámicamente en qué posición queremos añadir la cadena como esta

int r=k.nextInt(); 
Integer i6=new Integer(r); 
System.out.println("Enter the address"); 
String p6=k.nextLine(); 
ar3.add(i6,p6); 

no es excuting el después de leer el número entero

0

función de clonación en Arraylist no es igual que la copia de un ArrayList a otro, si utilizamos clone(), lleva a cabo la copia de ArrayList original, pero si hacemos cualquier cambio t o el arraylist original después del uso clone(), no afectará el arraylist copiado .. Ej:

public static void main(String[] a) { 

List list = new ArrayList(); 

list.add("A"); 

List list2 = ((List) ((ArrayList) list).clone()); 

System.out.println(list); 
System.out.println(list2); 

list.clear(); 

System.out.println(list); 
System.out.println(list2); 
} 

de salida: -

[A]

[A]

[]

[A]

0

Este hecho hace una copia superficial , aquí hay un comentario para clonar, desde el código fuente ArrayList

Devuelve una copia superficial de esta instancia de ArrayList. (Los propios elementos no se copian.)

Para entender esto, vamos a ver un fragmento en el método clone de ArrayList

v.elementData = Arrays.copyOf(elementData, size); 

Como sabemos, cuando nos asignar un objeto a una variable, JAVA no hace una copia nueva de ese objeto. En cambio, esta variable se convierte en otra referencia que apunta al Objeto original.

Por lo tanto, elementData en realidad está almacenando referencias a los objetos puestos en este ArrayList. Y clone solo copie estas referencias, no se crean réplicas de objetos.

Por supuesto, puede eliminar o agregar una nueva referencia a una ArrayList clonada.

Sin embargo, la modificación de Objetos antiguos en una ArrayList afectará a la ArrayList original. Es difícil hacer ilustraciones con tu ejemplo, ya que Integer es inmutable.

Para ver el efecto secundario, se puede definir un objeto personalizado mutable

class Person { 
     private int a; 

     public void setA(int a) { 
      this.a = a; 
     } 
     public int getA() { 
      return a; 
     } 
     @Override 
     public String toString() { 
      return String.valueOf(a); 
     } 
    } 

continuación, puede utilizar el siguiente código para hacer la prueba

 Person p1 = new Person(); 
     Person p2 = new Person(); 

     ArrayList<Person> tt = new ArrayList<Person>(); 
     tt.add(p1); 
     tt.add(p2); 

     ArrayList<Person> yy = (ArrayList<Person>) tt.clone(); 
     Person vv = yy.get(yy.indexOf(p2)); 
     vv.setA(12); 
     yy.remove(p1); 

     System.out.println("tt: " + tt); 
     System.out.println("yy: " +yy); 

La salida debe ser

tt: [0, 12]
yy: [12]

Vea el efecto secundario :)? Solo cambiamos el elemento en yy, pero también se refleja en tt.

1

Shallow Cloning es la estrategia de clonación predeterminada proporcionada por Object.clone() de la que está hablando. El método clone() de la clase de objeto crea una nueva instancia y copia todos los campos del objeto clonable a esa nueva instancia (ya sea primitiva o de referencia). Por lo tanto, en el caso de los tipos de referencia, solo los bits de referencia se copian en la nueva instancia, por lo tanto, la variable de referencia de ambos objetos apuntará al mismo objeto. El ejemplo que hemos visto arriba es un ejemplo de Clonación superficial.

Deep Cloning Como el nombre sugiere la clonación profunda significa clonar todo de un objeto a otro.Para lograr esto, necesitamos engañar a nuestro método clone() para proporcionar nuestra propia estrategia de clonación. Podemos hacerlo mediante la implementación de Cloneable interfaz y método clone anulación() en cada tipo de referencia que tenemos en nuestra jerarquía de objetos y luego llamamos super.clone() y estos métodos en clone() método clone de nuestro objeto.

Pero si nos fijamos en el método clone() de ArrayList en el código fuente, verá que está copiando el exterior v.elementData = Arrays.copyOf(elementData, size); después de llamar super.clone(), lo que significa clone() de ArrayList profundamente lo copia el contenido

public Object clone() { 
    try { 
     ArrayList<?> v = (ArrayList<?>) super.clone(); 
     v.elementData = Arrays.copyOf(elementData, size); 
     v.modCount = 0; 
     return v; 
    } catch (CloneNotSupportedException e) { 
     // this shouldn't happen, since we are Cloneable 
     throw new InternalError(e); 
    } 
} 

para leer más acerca de la clonación y sus tipos, como profunda clonación y la clonación poco profunda lea Java Cloning and Types of Cloning (Shallow and Deep) in Details with Example

Cuestiones relacionadas