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!