Cloning performing a deep copy and copy factory


Cloning performing a deep copy

To copy nested objects, a deep copy must be performed, as shown in this example.

import java.util.ArrayList;
import java.util.List;
 
public class CustomSheepClone implements Cloneable {
    private String sheepName;
    private int sheepWeight;
    private List<CustomSheepClone> offspring;
 
    public CustomSheepClone(String name, int weight) {
        this.sheepName = name;
        this.sheepWeight = weight;
    }
 
    @Override
    public Object clone() throws CloneNotSupportedException {
        CustomSheepClone clonedSheep = (CustomSheepClone) super.clone();
        if (offspring != null) {
            // make a deep copy of the offspring
            List<CustomSheepClone> clonedOffspring = new ArrayList<>(offspring.size());
            for (CustomSheepClone child : offspring) {
                clonedOffspring.add((CustomSheepClone) child.clone());
            }
            clonedSheep.setOffspring(clonedOffspring);
        }
        return clonedSheep;
    }
 
    public List<CustomSheepClone> getOffspring() {
        return offspring;
    }
 
    public void setOffspring(List<CustomSheepClone> offspring) {
        this.offspring = offspring;
    }
}
import java.util.Arrays;
import java.util.List;
 
public class SheepCloningExample {
    public static void main(String[] args) throws CloneNotSupportedException {
        // create a sheep
        Sheep originalSheep = new Sheep("Molly", 18);
 
        // create children
        Sheep childA = new Sheep("Lamb1", 3);
        Sheep childB = new Sheep("Lamb2", 4);
        originalSheep.setChildren(Arrays.asList(childA, childB));
 
        // clone the sheep
        Sheep clonedSheep = (Sheep) originalSheep.clone();
 
        List<Sheep> originalSheepChildren = originalSheep.getChildren();
        List<Sheep> clonedSheepChildren = clonedSheep.getChildren();
 
        for (int i = 0; i < originalSheepChildren.size(); i++) {
            // prints false, both lists contain copies of the objects inside
            System.out.println(originalSheepChildren.get(i) == clonedSheepChildren.get(i));
        }
    }
}
 
class Sheep implements Cloneable {
    private String name;
    private int age;
    private List<Sheep> children;
 
    public Sheep(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public void setChildren(List<Sheep> children) {
        this.children = children;
    }
 
    public List<Sheep> getChildren() {
        return children;
    }
 
    @Override
    protected Object clone() throws CloneNotSupportedException {
        Sheep clonedSheep = (Sheep) super.clone();
        // Assuming Sheep objects inside the list also implement Cloneable
        clonedSheep.setChildren(Arrays.asList((Sheep) children.get(0).clone(), (Sheep) children.get(1).clone()));
        return clonedSheep;
    }
}

Cloning using a copy factory

public class CustomSheep {
    private String sheepName;
    private int sheepWeight;
 
    public CustomSheep(String name, int weight) {
        this.sheepName = name;
        this.sheepWeight = weight;
    }
 
    public static CustomSheep createInstance(CustomSheep other) {
        return new CustomSheep(other.sheepName, other.sheepWeight);
    }
}

Basic Programs