This article is participating in “Java Theme Month – Java Development in Action”, see the activity link for details

The opening

This is the first day of my participation in Gwen Challenge

Have you had any problems with collection replication during development?

A normal collection copy simply copies the stack address block in memory so that a new collection object points to the address block, but the object variable in the collection points to the same area in the heap. So when the copied collection modifies the data in its own collection object, the source collection object also changes. This effect is called shallow copy of Java collection objects (that is, only copied on the stack, but not copied on the heap).

Deep replication, on the other hand, copies both stack and heap data so that the copied set has no relationship to the copied set.

Case presentation

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Demo {  
    private int  demoValue;  
}
Copy the code

Try shallow copying:

@Test  
public void testDemoCopy(a) {  
    // Here I create a collection of sources
    ArrayList<Demo> sourceCollection = new ArrayList<Demo>();  
    // Here I add some objects to the sourceCollection
    sourceCollection.add(new Demo(1));  
    sourceCollection.add(new Demo(2));  
    // Here I create a new empty collection
    ArrayList<Demo> newCollection = new ArrayList<Demo>();  
    newCollection.addAll(sourceCollection);  
    // Now I have modified some objects in the new collection
    newCollection.get(0).setDemoValue(3);  
    // Now we verify what it is in the source set
    for(Demo demo : sourceCollection){  
        System.out.println(demo.getDemoValue());  
    }   
    Assertion verifies whether the source Collection has been modified.
    Assert.assertEquals(sourceCollection.get(0).getDemoValue(),1);  
}
Copy the code

It is obvious that the Demo object changed in the newCollection is also changed in the SourceCollection, indicating that the Demo object in both collections is the same object. This is also the downside of shallow copying.

So how do you separate the two sets, how do you do deep copy?

Try deep copying:

We’ll start with the Demo class, which implements the Cloneable interface, and rewrite its Clone method

protected Demo clone(a) throws CloneNotSupportedException {             
   return (Demo)super.clone();  
}
Copy the code

The test classes are as follows

@Test  
public void testCopyDeep(a) throws Exception{  
    ArrayList<Demo> sourceCollection = new ArrayList<Demo>();  
    sourceCollection.add(new Demo(1));  
    sourceCollection.add(new Demo(2));    
      
    ArrayList<Demo> newCollection = new ArrayList<Demo>();  
    for(Demo demo : sourceCollection){  
        // Here is the point
        newCollection.add(demo.clone());  
    }  
    newCollection.get(0).setDemoValue(3);  
    for(Demo demo : sourceCollection){  
        System.out.println(demo.getDemoValue());  
    }  
    Assert.assertEquals(sourceCollection.get(0).getDemoValue(),1);  
}
Copy the code

Finally, let’s observe the result: the two collections are independent, and no modification affects each other’s objects

Another way to write a fast copy set

Java lambda expressions can be semantically optimized, as shown in the following example:

👍 ❤️ Don’t get lost

The article continues to update every week, you can search wechat “ten minutes to learn programming” the first time to read and urge more, if this article is not bad, feel something if you support and recognition, is the biggest power of my creation, we will see the next article!