จากบทความที่แล้วนะครับ จะเป็นการใช้แนวคิด Shallow Copy กับ Deep Copy ใน .Net Framework ภาษา C# ครับ คราวนี้มาถึงตาม Java บ้างครับ
เปิดมาที่ Code เลยครับ
import java.util.ArrayList;
import java.util.List;
class Person implements Cloneable {
private String name;
private List<String> nicknames;
public Person(String name) {
this.name = name;
this.nicknames = new ArrayList<>();
}
public void addNickname(String nickname) {
this.nicknames.add(nickname);
}
public List<String> getNicknames() {
return nicknames;
}
// Shallow Copy
public Person shallowCopy() throws CloneNotSupportedException {
return (Person) super.clone();
}
// Deep Copy
public Person deepCopy() {
Person clonedPerson = new Person(this.name);
for (String nickname : this.nicknames) {
clonedPerson.addNickname(new String(nickname));
}
return clonedPerson;
}
@Override
public String toString() {
return "Person{name='" + name + '\'' + ", nicknames=" + nicknames + '}';
}
}
public class DeepCopyVsShallowCopy {
public static void main(String[] args) throws CloneNotSupportedException {
Person original = new Person("Chatri");
original.addNickname("ping");
original.addNickname("pingkung");
// Shallow copy
Person shallowCopied = original.shallowCopy();
shallowCopied.getNicknames().add("naiwaen");
// Deep copy
Person deepCopied = original.deepCopy();
deepCopied.getNicknames().add("CN");
System.out.println("Original: " + original);
System.out.println("Shallow Copied: " + shallowCopied);
System.out.println("Deep Copied: " + deepCopied);
}
}ใน Blog ผมเตรียม Class Person ไว้ โดยมี Get / Set ปกติ และทำ
- Shallow Copy ใน Method shallowCopy อันนี้ผมใช้ความสามารถของ Cloneable เข้ามาช่วยครับ
// Shallow Copy
public Person shallowCopy() throws CloneNotSupportedException {
return (Person) super.clone();
}จริงๆ ถ้าไม่อยากเขียนแบบนี้มันมีตัว BeanUtils.copyProperties ที่ช่วยทำ Shallow Copy ให้ครับ แต่มันมีความพิสดารของ Spring / Apache Common Param มันจะสลับกันครับ
Ref: https://stackoverflow.com/a/34988281
- Deep Copy อันนี้ใช้วิํธี New Object แล้ว Loop ยัดค่าใหม่ ได้คนละ Reference แน่ๆครับ
// Deep Copy
public Person deepCopy() {
Person clonedPerson = new Person(this.name);
for (String nickname : this.nicknames) {
clonedPerson.addNickname(new String(nickname));
}
return clonedPerson;
}Result
- ตรง original จริงถ้าดูจาก Code มันจะยัด nicknames แต่ 2 ตัว ping, pingkung เท่านั้นครับ แต่เนื่องจากเป็น Shallow Copy ไปที่ shallowCopied เลยแก้ค่าได้ ตอน Print เลยมี naiwaen โผลขึ้นมา
- ส่วน deepCopied อันนี้ มันตั้งต้น 3 อันอยู่แล้ว ตัว Original โดน Shallow Copy เติมค่าไป
แล้วที่นี้มีเติมค่า CN ต่อไปอีกนั้น แต่เนื่องจากมันเป็น Deep copy มันเลยไม่ Effect ไป shallowCopied / original
Original: Person{name='Chatri', nicknames=[ping, pingkung, naiwaen]}
Shallow Copied: Person{name='Chatri', nicknames=[ping, pingkung, naiwaen]}
Deep Copied: Person{name='Chatri', nicknames=[ping, pingkung, naiwaen, CN]}Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.



