Deep copy of an instance of an array of objects, Java

I have an object made in my main Recipe recipeOne = new Recipe("Pepperoni Pizza");

This object is an instance of this array of objects, defined and built here!

 public class Recipe implements Cloneable{ String Name; final int INGREDIENT_ARRAY_MAX = 10; Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX]; public Recipe(String name){ Name = name; } 

So, I want to make a deep copy of this object with the line Recipe ressippi = (Recipe) recipe.clone(); and he will send me here!

 public Object clone(){ Recipe cloneRec = new Recipe(Name); return cloneRec; } 

I know that this is currently a shallow copy, because the method passes only links, so if I tried to change the name on my new object, which was a clone of recipeOne ... it would change both of their names. Obviously, I do not want this, I am pretty lost on this, can anyone help?

EDIT: @Rohit Jain

Both my Recipe class and my Ingredient class (objects that are stored in an array of recipes) have toString methods and ingredient recipes to print everything in a nice small format. When I call it my recipeOne object (the one called pepperoni pizza), I get Pepperoni Pizza: 1.0 pounds of dough, 8.0 ounces of sauce, 10.0 ounces of cheese

Then I go on to make a ressippi object and set it to the recipeOne clone, so everything is fine from here ... Then I change the name of ressippi to โ€œPineapple Pizzaโ€ and it prints fine, but it does not print 3 ingredient objects that recipeOne kept what it should do!

+4
source share
3 answers

Add a copy constructor to the recipe class, which creates a new instance of the recipe and copies all the fields from the original recipe.

Recipe.java

 public class Recipe implements Cloneable { String name; final int INGREDIENT_ARRAY_MAX = 10; Ingredient[] ingredients = new Ingredient[INGREDIENT_ARRAY_MAX]; public Recipe(String name) { this.name = name; } //Copy Constructor private Recipe(Recipe recipe){ this.name = recipe.name; for(int x = 0; x < recipe.ingredients.length; x++){ this.ingredients[x] = recipe.ingredients[x]; } } public static Recipe newInstance(Recipe recipe){ return new Recipe(recipe); } //Debug Method public static void printRecipe(Recipe recipe){ System.out.println("Recipe: " + recipe.name); for(Ingredient i:recipe.ingredients){ if(i != null && i.getName() != null){ System.out.println("Ingredient: " + i.getName()); } } } //Test Method public static void main(String[] args) { Recipe recipe = new Recipe("Chicken Soup"); recipe.ingredients[0] = new Ingredient("Chicken"); recipe.ingredients[1] = new Ingredient("Broth"); Recipe copy = new Recipe(recipe); copy.ingredients[2] = new Ingredient("Rice"); copy.name = "Chicken Rice Soup"; printRecipe(recipe); printRecipe(copy); System.out.println(recipe == copy); System.out.println(recipe.ingredients == copy.ingredients); } } 

Ingredient.java

 public class Ingredient { private String name; public Ingredient(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 
+3
source

As you found out, the Cloneable implementation does not actually clone the object. You will need to use the clone() method wisely, and if you want to get a deep copy, then you have to implement it.

Now creating a new Recipe object with the same Name attribute is fine. And changing the name for the new object afterwards is also quite normal, it will not change the name of the first object, since java String are immutable.

You might want to take a look at the commons-beanutils package , which provides convenient code for cloning objects.

Finally, as for "... only passes links ...", you should read, for example. this and this thread.

Greetings

+1
source

Serialize it! Take a look at the deepClone function discussed here: http://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html

Other answers to strings that are immutable are true of course, but the problem you tried to describe with the String example was just a bad example; complex objects, such as an array of Ingredients, are still copied by reference.

Also: change the name of your array so that it does not match the class name (= confusing):

 Ingredient Recipe[] = new Ingredient[INGREDIENT_ARRAY_MAX]; 
+1
source

All Articles