diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/Balance.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/Balance.java new file mode 100644 index 0000000000..3a89a29baf --- /dev/null +++ b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/Balance.java @@ -0,0 +1,38 @@ +package com.baeldung.java_shallow_deep_copy.data; + +public class Balance implements Cloneable { + + private float amount; + private String currency; + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } + + public Balance(float amount, String currency) { + this.amount = amount; + this.currency = currency; + } + + //Copy constructor + public Balance(Balance balance) { + this(balance.getAmount(), balance.getCurrency()); + } + + public float getAmount() { + return amount; + } + + public void setAmount(float amount) { + this.amount = amount; + } + + public String getCurrency() { + return currency; + } + + public void setCurrency(String currency) { + this.currency = currency; + } +} diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccount.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccount.java new file mode 100644 index 0000000000..191ce8aa7d --- /dev/null +++ b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccount.java @@ -0,0 +1,38 @@ +package com.baeldung.java_shallow_deep_copy.data; + +public class BankAccount implements Cloneable { + + protected String name; + protected String surname; + protected Balance balance; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + public Balance getBalance() { + return balance; + } + + public void setBalance(Balance balance) { + this.balance = balance; + } + + public BankAccount(String name, String surname, Balance balance) { + this.name = name; + this.surname = surname; + this.balance = balance; + } +} diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccountDeep.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccountDeep.java new file mode 100644 index 0000000000..17a61fe2f7 --- /dev/null +++ b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccountDeep.java @@ -0,0 +1,17 @@ +package com.baeldung.java_shallow_deep_copy.data; + +public class BankAccountDeep extends BankAccount { + + public BankAccountDeep(String name, String surname, Balance balance) { + super(name, surname, balance); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return new BankAccountDeep(name, surname, (Balance) balance.clone()); + } + + public BankAccountDeep(BankAccountDeep bankAccountDeep) { + this(bankAccountDeep.name, bankAccountDeep.surname, new Balance(bankAccountDeep.balance)); + } +} diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccountShallow.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccountShallow.java new file mode 100644 index 0000000000..932a93c69f --- /dev/null +++ b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/BankAccountShallow.java @@ -0,0 +1,17 @@ +package com.baeldung.java_shallow_deep_copy.data; + +public class BankAccountShallow extends BankAccount { + + public BankAccountShallow(String name, String surname, Balance balance) { + super(name, surname, balance); + } + + public BankAccountShallow(BankAccountShallow shallow) { + this(shallow.name, shallow.surname, shallow.balance); + } + + @Override + public Object clone() throws CloneNotSupportedException { + return super.clone(); + } +} diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/Person.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/Person.java deleted file mode 100644 index e52a669e28..0000000000 --- a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/Person.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.baeldung.java_shallow_deep_copy.data; - -import java.util.List; - -public class Person { - - private String name; - private String surname; - private List addresses; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getSurname() { - return surname; - } - - public void setSurname(String surname) { - this.surname = surname; - } - - public List getAddresses() { - return addresses; - } - - public void setAddresses(List addresses) { - this.addresses = addresses; - } -} diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/PersonDeep.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/PersonDeep.java deleted file mode 100644 index a2823566b8..0000000000 --- a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/PersonDeep.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.baeldung.java_shallow_deep_copy.data; - -import java.util.ArrayList; -import java.util.List; - -public class PersonDeep extends Person{ - - public PersonDeep(String name, String surname, List addresses) { - this.setName(name); - this.setSurname(surname); - List deepCopyList = new ArrayList<>(); - deepCopyList.addAll(addresses); - this.setAddresses(deepCopyList); - } -} diff --git a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/PersonShallow.java b/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/PersonShallow.java deleted file mode 100644 index 2221d8b924..0000000000 --- a/java-shallow-deep-copy/src/main/java/com/baeldung/java_shallow_deep_copy/data/PersonShallow.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.baeldung.java_shallow_deep_copy.data; - -import java.util.List; - -public class PersonShallow extends Person { - - public PersonShallow(String name, String surname, List addresses) { - this.setName(name); - this.setSurname(surname); - this.setAddresses(addresses); - } - - -} diff --git a/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/DeepCopyTest.java b/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/DeepCopyTest.java index 5fbdbabad5..01a73f8d98 100644 --- a/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/DeepCopyTest.java +++ b/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/DeepCopyTest.java @@ -1,26 +1,53 @@ package com.baeldung.java_shallow_deep_copy.unit; -import com.baeldung.java_shallow_deep_copy.data.PersonDeep; -import com.baeldung.java_shallow_deep_copy.data.PersonShallow; -import org.junit.jupiter.api.Assertions; +import com.baeldung.java_shallow_deep_copy.data.*; + import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; +import static org.junit.jupiter.api.Assertions.assertNotEquals; public class DeepCopyTest { + private static final String NAME = "Hello"; + private static final String SURNAME = "World"; + @Test - void whenTheParameterIsNotAnImmutableObject_thenShouldDoADeepCopy (){ + void whenIsADeepCopyDoneByCopyConstructor_thenNestedObjectShouldNotHaveSameReference() { + Balance balance = new Balance(10000, "EUR"); + BankAccountDeep bankAccount = new BankAccountDeep(NAME, SURNAME, balance); + BankAccountDeep deepCopy = new BankAccountDeep(bankAccount); + assertNotEquals(bankAccount.getBalance(), deepCopy.getBalance()); + } + + @Test + void whenIsADeepCopyDoneByCopyConstructor_thenCopyValueShouldNotChange() { + Balance balance = new Balance(10000, "EUR"); + BankAccountDeep bankAccount = new BankAccountDeep(NAME, SURNAME, balance); + BankAccountDeep deepCopy = new BankAccountDeep(bankAccount); + balance.setAmount(0); + assertNotEquals(bankAccount.getBalance() + .getAmount(), deepCopy.getBalance() + .getAmount()); + } + + @Test + void whenIsADeepCopyDoneByCloneMethod_thenNestedObjectShouldNotHaveSameReference() throws CloneNotSupportedException { String name = "Hello"; String surname = "World"; - List addresses = new ArrayList<>(); - addresses.add("Standford street"); - PersonDeep personShallow = new PersonDeep(name,surname,addresses); - personShallow.getAddresses().forEach(System.out :: println); - Assertions.assertEquals(addresses, personShallow.getAddresses()); - addresses.add("Oxford street"); - personShallow.getAddresses().forEach(System.out :: println); - Assertions.assertNotEquals(addresses, personShallow.getAddresses()); + Balance balance = new Balance(10000, "EUR"); + BankAccountDeep bankAccount = new BankAccountDeep(NAME, SURNAME, balance); + BankAccountDeep deepCopy = (BankAccountDeep) bankAccount.clone(); + assertNotEquals(bankAccount.getBalance(), deepCopy.getBalance()); + } + + @Test + void whenIsADeepCopyDoneByCloneMethod_thenCopyValueShouldNotChange() throws CloneNotSupportedException { + + Balance balance = new Balance(10000, "EUR"); + BankAccountDeep bankAccount = new BankAccountDeep(NAME, SURNAME, balance); + BankAccountDeep deepCopy = (BankAccountDeep) bankAccount.clone(); + balance.setAmount(0); + assertNotEquals(balance.getAmount(), deepCopy.getBalance() + .getAmount()); } } diff --git a/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/ShallowCopyTest.java b/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/ShallowCopyTest.java index daef700145..3b59d8765d 100644 --- a/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/ShallowCopyTest.java +++ b/java-shallow-deep-copy/src/test/java/com/baeldung/java_shallow_deep_copy/unit/ShallowCopyTest.java @@ -1,38 +1,62 @@ package com.baeldung.java_shallow_deep_copy.unit; -import com.baeldung.java_shallow_deep_copy.data.PersonShallow; -import org.junit.jupiter.api.Assertions; +import com.baeldung.java_shallow_deep_copy.data.Balance; +import com.baeldung.java_shallow_deep_copy.data.BankAccountShallow; + import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; - +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; public class ShallowCopyTest { @Test - void whenTheParameterIsAnImmutableObject_thenShouldNotChangeTheValue (){ + void whenIsAShallowCopyDoneByCopyConstructor_thenImmutableObjectWillNotChange() { String name = "Hello"; String surname = "World"; - PersonShallow personShallow = new PersonShallow(name,surname,null); + BankAccountShallow personShallow = new BankAccountShallow(name, surname, null); surname = "Pluto"; - Assertions.assertNotEquals(surname, personShallow.getSurname()); + assertNotEquals(surname, personShallow.getSurname()); } @Test - void whenTheParameterIsNotAnImmutableObject_thenShouldDoAShallowCopy (){ - String name = "Hello"; - String surname = "World"; - List addresses = new ArrayList<>(); - addresses.add("Standford street"); - PersonShallow personShallow = new PersonShallow(name,surname,addresses); - personShallow.getAddresses().forEach(System.out :: println); - Assertions.assertEquals(addresses, personShallow.getAddresses()); - addresses.add("Oxford street"); - personShallow.getAddresses().forEach(System.out :: println); - Assertions.assertEquals(addresses, personShallow.getAddresses()); + void whenIsAShallowCopyDoneByCopyConstructor_thenNestedObjectsAreTheSame() { + Balance balance = new Balance(10000, "EUR"); + BankAccountShallow bankAccount = new BankAccountShallow("Hello", "World", balance); + BankAccountShallow shallowCopy = new BankAccountShallow(bankAccount.getName(), bankAccount.getSurname(), bankAccount.getBalance()); + assertEquals(bankAccount.getBalance(), shallowCopy.getBalance()); } + @Test + void whenIsAShallowCopyDoneByCopyConstructor_thenCopyValueShouldChange() throws CloneNotSupportedException { + Balance balance = new Balance(10000, "EUR"); + BankAccountShallow bankAccount = new BankAccountShallow("Hello", "World", balance); + BankAccountShallow shallowCopy = new BankAccountShallow(bankAccount); + float newBalance = 0; + balance.setAmount(newBalance); + assertEquals(newBalance, bankAccount.getBalance() + .getAmount()); + assertEquals(newBalance, shallowCopy.getBalance() + .getAmount()); + } + @Test + void whenIsAShallowCopyDoneByCloneMethod_thenNestedObjectsAreTheSame() throws CloneNotSupportedException { + Balance balance = new Balance(10000, "EUR"); + BankAccountShallow bankAccount = new BankAccountShallow("Hello", "World", balance); + BankAccountShallow shallowCopy = (BankAccountShallow) bankAccount.clone(); + assertEquals(bankAccount.getBalance(), shallowCopy.getBalance()); + } + + @Test + void whenIsAShallowCopyDoneByCloneMethod__thenCopyValueShouldChange() throws CloneNotSupportedException { + Balance balance = new Balance(10000, "EUR"); + BankAccountShallow bankAccount = new BankAccountShallow("Hello", "World", balance); + BankAccountShallow shallowCopy = (BankAccountShallow) bankAccount.clone(); + float newBalance = 0; + balance.setAmount(newBalance); + assertEquals(newBalance, shallowCopy.getBalance() + .getAmount()); + } }