2010-04-07 5 views
13

J'ai besoin d'une copie superficielle d'un Java ArrayList, devrais-je utiliser ou itérer sur la liste originale et copier des éléments dans new arrayList, ce qui est plus rapide?ArrayList copie superficielle iterate ou clone()

+1

Lors de la saisie de la question, vous auriez dû voir apparaître une liste de questions connexes (la même liste que vous voyez dans la colonne en bas à droite de cette page). Avez-vous regardé autour d'eux? Pourquoi ces réponses n'étaient-elles pas suffisantes? S'il vous plaît élaborer. – BalusC

+0

Je suis allé sur le pop up. Il n'y avait rien de lié à la performance en termes de itérateur ArrayList vs clone(). – tech20nn

Répondre

9

Utilisez clone(), ou utilisez le constructeur de copie.

Le constructeur de copie effectue une transformation supplémentaire de la collection transmise à la matrice, tandis que la méthode clone() utilise directement la matrice interne.

Gardez à l'esprit que clone() renvoie Object, vous devrez donc passer à List.

+0

Exactement j'ai regardé le code source java.util.ArrayList et j'ai trouvé que le clone() utilise Array.copyof, ce qui serait beaucoup plus efficace que de boucler sur l'original ArrayList. clone public Object() {try { @SuppressWarnings ("non vérifiées") ArrayList v = (ArrayList ) super.clone(); v.elementData = Arrays.copyOf (elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // cela ne devrait pas arriver, puisque nous sommes Cloneable throw new InternalError(); } } – tech20nn

+1

Je ne m'inquiéterais pas beaucoup de l'efficacité. L'utilisation de clone() est une douleur; utilisez simplement le constructeur de conversion comme suggéré. –

+2

@Kevin Bourrillion Pourquoi pensez-vous que l'utilisation de 'clone()' est une douleur? Implémenter 'clone()' est une douleur, ne pas l'utiliser. – Bozho

8

Au lieu d'effectuer une itération manuelle, vous pouvez utiliser le copy constructor.

Quant à la différence de vitesse entre cela et l'utilisation clone():

  1. Peu importe
  2. Très probablement il n'y a pas
  3. Faites une référence pour votre configuration spécifique du système et cas d'utilisation
+0

@ Michael..Merci. J'ai vérifié le code pour le constructeur de copie. Il a une étape supplémentaire pour retourner la structure de tableau interne de copie comme Bozho mentionné. ArrayList (Collection c) { elementData = c.toArray(); size = élémentData.length; if (elementData.getClass()! = Object []. Class) elementData = Arrays.copyOf (élémentData, taille, Object []. Class); } – tech20nn

+0

J'aime l'universel "dois-je optimiser?" motif de pensée –

-1

la question dit shallowcopy pas deepcopy.Copying référence directement à partir d'une référence arraylist à une autre fonctionnera également right.Ceep copie comprend copie individuelle élément dans arraylist.

ArrayList<Integer> list=new ArrayList<Integer>(); 
list.add(3); 
ArrayList<Integer> list1=list; //shallow copy... 

Y at-il un problème dans ce ??

+2

Ceci est faux. Tout ce qui va faire, c'est qu'il y aura deux pointeurs vers un objet physique 'ArrayList' en mémoire. L'ajout d'un 'Integer' à une liste fait apparaître' Integer' aussi dans l'autre liste. Ce n'est pas ce que nous voulons. La copie superficielle permet aux objets sous-jacents de partager le même espace mémoire, mais les listes doivent avoir un espace mémoire séparé. Donc, si vous modifiez un 'Integer', il sera modifié dans les deux listes. Mais si vous ajoutez un 'Integer' dans une liste, il n'apparaîtra pas dans l'autre liste. Une copie en profondeur ne reflétera aucun changement à quoi que ce soit dans l'autre liste. – Antimonit