How to Clone collections--arraylist and HashSet deep copy in Java

Source: Internet
Author: User
Tags addall shallow copy

Programmers often misuse the copy constructors provided by each collection class as clones, List Set ArrayList HashSet or methods implemented by other collections. It should be remembered that the copy constructor for the Java collection only provides a shallow copy rather than a deep copy, which means that the objects stored in the original list and the clone list are the same, pointing to the same location in the Java heap memory. One of the reasons for this misunderstanding is the shallow cloning of a set of immutable objects. Because of immutability, it is possible even if two sets point to the same object. The string pool contains a string that is the case, and changing one does not affect the other. ArrayListA problem occurs when you use a copy constructor to create a copy of an employee list, and the Employee class is not immutable. In this case, if the original collection modifies the employee information, the change is also reflected in the Clone collection. Similarly, if the Clone collection employee information changes, the original collection is also changed. In most cases, this change is not what we want, and the cloned object should be independent of the original object. The solution to this problem is to deeply clone the collection , and the deep clone will recursively clone the object to the base data type or to the immutable class. This article will look ArrayList HashSet at a method of deep copy or a collection class. If you understand the difference between a deep copy and a shallow copy, then it is easy to understand how a set of deep clones is understood.

Deep cloning of Java collections

The following example has a Employee collection where employee is a mutable object, a member variable, name and a designation . They are stored in HashSet . java.util.CollectionCreate a copy of the collection using the method of the interface addAll() . Then modify the value of each object stored in the original collection Employee designation . Ideally this change will not affect the Clone collection, because the Clone collection and the original collection should be independent of each other, but the clone collection is also changed. The way to fix this problem is to Collection deeply clone the elements stored in the class.

1 /**2  * 3 * @ClassName: Collectioncloningtest4 * TODO5  * @authorXingle6 * @date 2015-3-20 pm 3:32:227  */8  Public classCollectioncloningtest {9     Ten      Public Static voidMain (string[] args) { Onearraylist<employee> org =NewArraylist<employee>(); AOrg.add (NewEmployee ("Joe", "Manager"));  -Org.add (NewEmployee ("Tim", "Developer"));  -Org.add (NewEmployee ("Frank", "Developer"));  the                 -collection<employee> copy =NewHashset<>(org);  -          -System.out.println ("original collection:" +org); +System.out.println ("copied collection:" +copy); -          +Iterator<employee> Orgitr =org.iterator (); A          while(Orgitr.hasnext ()) { atOrgitr.next (). Setdesignation ("Staff"));  -              -         } -  -System.out.println ("Modified original collection:" +org); -System.out.println ("copied collection after modification:" +copy); in     } -  to } +  -  the classEmployee{  *     PrivateString name; $     PrivateString designation;Panax Notoginseng       -      PublicEmployee (string name, string designation) { the          This. Name =name; +          This. designation =designation; A     }  the       +      PublicString getdesignation () { -         returndesignation; $     }  $   -      Public voidsetdesignation (String designation) { -          This. designation =designation; the     }  -  Wuyi      PublicString GetName () { the         returnname; -     }  Wu   -      Public voidsetName (String name) { About          This. Name =name; $     }  -   - @Override -      PublicString toString () { A         returnString.Format ("%s:%s", name, designation);  +     }  the  -}

Execution Result:

You can see that changing the original Collection Employee object (changing designation to " staff ") is also reflected in the Clone collection, because the clone is a shallow copy, pointing to the same object in the heap Employee . To fix this problem, you need to iterate through the collection, deep-clone the Employee object, and before that, rewrite the Employee object's Clone method.

1) Employee Implement Cloneable interface
2) Employee Add the following method to the class clone()

3) Do not use the copy constructor, use the following code to deep copy the collection

1  Public classCollectioncloningtest {2     3      Public Static voidMain (string[] args) {4arraylist<employee> org =NewArraylist<employee>();5Org.add (NewEmployee ("Joe", "Manager")); 6Org.add (NewEmployee ("Tim", "Developer")); 7Org.add (NewEmployee ("Frank", "Developer")); 8                9        //collection<employee> copy = new hashset<> (org);Tencollection<employee> copy =NewHashset<employee>(Org.size ()); One                  A          -System.out.println ("original collection:" +org); -System.out.println ("copied collection:" +copy); the          -Iterator<employee> Orgitr =org.iterator (); -          while(Orgitr.hasnext ()) { -             //Orgitr.next (). Setdesignation ("Staff"); + Copy.add (Orgitr.next (). Clone ());  -              +         } A          at  -Iterator<employee> ORGITR2 =org.iterator (); -          while(Orgitr2.hasnext ()) { -Orgitr2.next (). Setdesignation ("Staff"));  -         }  -System.out.println ("Modified original collection:" +org); inSystem.out.println ("copied collection after modification:" +copy); -     } to  + } -  the  * classEmployeeImplementscloneable{ $     PrivateString name;Panax Notoginseng     PrivateString designation; -       the      PublicEmployee (string name, string designation) { +          This. Name =name; A          This. designation =designation; the     }  +       -      PublicString getdesignation () { $         returndesignation; $     }  -   -      Public voidsetdesignation (String designation) { the          This. designation =designation; -     } Wuyi   the      PublicString GetName () { -         returnname; Wu     }  -   About      Public voidsetName (String name) { $          This. Name =name; -     }  -   - @Override A      PublicString toString () { +         returnString.Format ("%s:%s", name, designation);  the     }  -      $ @Override the     protectedEmployee Clone () { the         Try { theEmployee result = (employee)Super. Clone (); the             returnresult; -}Catch(clonenotsupportedexception e) { in              Throw NewRuntimeException (e);//won ' t happen the         } the          About     } the}

Execution Result:

You can see that the Clone collection and the original collection are independent of each other, pointing to different objects.

This is how the contents of a collection are cloned in Java . Now we know that a copy constructor List or Set a method of a collection class addAll() only creates a shallow copy of the collection, and the original and cloned collections point to the same object. To avoid this problem, you should clone the collection deeply and iterate through the collection to clone each element. Although this requires that the objects in the collection must support deep cloning operations.

How to Clone collections--arraylist and HashSet deep copy in Java

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.