Monday, 19 September 2016

Deep Copy of Object Array Instance, Java




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



This object is an instance of this Object Array defined and constructed 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 am looking to make a deep copy of this object with the line Recipe ressippi = (Recipe) recipe.clone(); and it sends me here!



public Object clone(){

Recipe cloneRec = new Recipe(Name);

return cloneRec;

}



I know this is currently a shallow copy because the method only passes references, so if I was to attempt a name change on my new Object that was a clone of recipeOne...it would change both of their names. Obviously I do not want that, I'm fairly lost on this, can anyone help?



EDIT:@Rohit Jain



Both my Recipe class as well as my Ingredient class (the objects the recipe array holds) have toString methods and recipes calls on ingredients in order to print it all out in a nice little format. When I call it on 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 proceed to make the object ressippi and set that to the clone of recipeOne, so all good from here...then I change ressippi's name to "Pineapple Pizza" and that prints out fine but it doesnt print the 3 ingredient objects that recipeOne stored, which it is suppose to do!


Answer



Add a copy constructor to the recipe class, which creates a new instance of recipe and copies all of the fields from an 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;
}
}

No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...