Comment faire une copie séparée d’une ArrayList?

Dupliquer possible:
Java: comment cloner ArrayList mais aussi cloner ses éléments?

J’ai un exemple de programme comme celui-ci:

ArrayList orginalInvoice = new ArrayList(); //add some items into it here ArrayList copiedInvoice = new ArrayList(); copiedInvoice.addAll(orginalInvoice); 

Je pensais pouvoir modifier des éléments à l’intérieur de la copiedInvoice et cela n’affecterait pas ces éléments dans originalInoice . Mais je me trompais.

Comment puis-je créer une copie / un clone séparé d’une ArrayList ?

Merci

Oui, c’est correct – vous devez implémenter clone() (ou un autre mécanisme approprié pour copier votre object, car clone() est considéré comme “cassé” par de nombreux programmeurs). Votre méthode clone() doit effectuer une copie complète de tous les champs mutables de votre object. De cette manière, les modifications apscopes à l’object cloné n’affecteront pas l’original.

Dans votre exemple de code, vous créez un deuxième ArrayList et le ArrayList avec des références aux mêmes objects . C’est pourquoi les modifications apscopes à l’object sont visibles à partir des deux List . Avec l’approche clone, votre code ressemblerait à ceci:

 List originalList = ...; // Create new List with same capacity as original (for efficiency). List copy = new ArrayList(originalList.size()); for (Foo foo: originalList) { copy.add((Foo)foo.clone()); } 

EDIT : pour clarifier, le code ci-dessus effectue une copie complète de la List origine, la nouvelle List contenant des références à des copies des objects d’origine. Cela contraste avec l’appel de ArrayList.clone() , qui effectue une shallow copy de la List . Dans ce contexte, une copie superficielle crée une nouvelle instance List mais contenant des références aux objects originaux.

Si vous stockez des objects mutables dans ArrayList, vous devrez copier chaque object lorsque vous copiez ArrayList. Sinon, la nouvelle ArrayList conservera les références d’origine.

Cependant, si vous stockez des objects immuables, vous pouvez utiliser:

ArrayList copiedInvoice = new ArrayList(originalInvoice);

Je pensais pouvoir modifier des éléments à l’intérieur de la facture copiée et cela n’affecterait pas ces éléments dans originalInoice.

Cela se produit car ce qui est copié est la variable de référence et non l’object lui-même.

Par conséquent, vous vous retrouvez avec deux “références” pointant vers le même object.

Si vous devez copier l’object entier, vous devrez peut-être le cloner.

Mais vous pourriez avoir des problèmes si vous ne clonez pas les atsortingbuts internes de l’object s’ils se trouvent être d’autres objects.

Par exemple, la définition de classe suivante ne vous pose aucun problème.

  public class Something { private int x; private int y; private Ssortingng ssortingngObject; } 

Si vous en créez une copie, vous copiez les valeurs actuelles de ses atsortingbuts et c’est tout.

Mais si votre classe a un autre object à l’intérieur, vous pourriez aussi envisager de le cloner.

  class OtherSomething { Something something; private int x; } 

Si vous procédez comme suit:

  Something shared = new Something(); OtherSomething one = new OtherSomething(); OtherSomething two = new OtherSomething(); one.something = shared; two.something = shared; 

Dans ce cas, une et deux ont la même variable de référence pour le même “quelque chose” partagé et changer la valeur dans l’une affecterait l’autre.

C’est pourquoi il est beaucoup plus simple / meilleur / plus facile d’utiliser des objects immuables.

Si vous devez modifier la valeur d’un object immuable, créez simplement un nouvel object avec la valeur correcte.

Jetez un oeil à ByteArrayOutputStream et ByteArrayInputStream. Si toutes vos classes implémentent Serializable, vous pouvez faire une copie en utilisant les classes mentionnées ci-dessus.