จากบทความที่แล้วนะครับ จะเป็นการใช้แนวคิด 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.