1. การเปรียบเทียบ

โปรแกรมเมอร์จำเป็นต้องเปรียบเทียบตัวแปรต่างๆ กับตัวแปรอื่นตลอดเวลา แต่อย่างที่คุณได้เห็นแล้วทุกอย่างไม่ง่ายนัก

จำนวนเต็มนั้นง่ายต่อการเปรียบเทียบ — คุณแค่ใช้==และทำเสร็จแล้ว ในการเปรียบเทียบจำนวนจริงคุณต้องเปรียบเทียบผลต่าง (หรือมากกว่า ค่าสัมบูรณ์ของผลต่าง) กับจำนวนที่น้อยมาก

การเปรียบเทียบสตริงนั้นยากยิ่งขึ้น เหนือสิ่งอื่นใด เป็นเพราะสตริงเป็นวัตถุ ยิ่งไปกว่านั้น โปรแกรมเมอร์มักต้องการให้การเปรียบเทียบสตริงแตกต่างกันเล็กน้อยขึ้นอยู่กับสถานการณ์


2. สตริงจัดเรียงหน่วยความจำอย่างไร

ดังที่คุณได้เห็นแล้ว สตริงถูกจัดเก็บไว้ในหน่วยความจำที่แตกต่างจากจำนวนเต็มและจำนวนจริง:

หน่วยความจำจัดเรียงสตริงอย่างไร

หน่วยความจำสองบล็อกถูกใช้เพื่อจัดเก็บสตริง: บล็อกหนึ่งจัดเก็บข้อความเอง (ขนาดขึ้นอยู่กับขนาดของข้อความ) ในขณะที่บล็อกที่สอง (4 ไบต์) เก็บที่อยู่ของบล็อกแรก

แม้ว่าโปรแกรมเมอร์ที่มีประสบการณ์จะบอกว่า " String strตัวแปรเก็บการอ้างอิงไปยังStringวัตถุ


3. การกำหนดการอ้างอิงให้กับสตริง

ประโยชน์ของแนวทางนี้จะชัดเจนเมื่อคุณต้องการกำหนดตัวแปรสตริงหนึ่งตัวให้กับตัวแปรสตริงอื่น ตัวอย่าง:

String text = "This is a very important message";
String message = text;

และนี่คือสิ่งที่หน่วยความจำจะมีเป็นผลลัพธ์:

การกำหนดการอ้างอิงให้กับสตริง

หลังจากการดำเนินการกำหนดประเภทนี้Stringวัตถุจะยังคงอยู่ที่เดิม และมีเพียงที่อยู่ของมัน (การอ้างอิงถึงวัตถุ) จะถูกคัดลอกลงในmessageตัวแปร


4. การทำงานกับการอ้างอิงและวัตถุ

แต่ถ้าคุณตัดสินใจแปลงสตริงเป็นตัวพิมพ์ใหญ่ (ตัวพิมพ์ใหญ่) เครื่อง Java ทำทุกอย่างถูกต้อง: คุณจะลงเอยด้วยสองStringออบเจกต์ และtextตัวแปรmessageและ จะจัดเก็บการอ้างอิง โดยแต่ละอ็อบเจ็กต์ของตัวเอง

ตัวอย่าง:

String text = "This is a very important message";
String message = text.toUpperCase(); 

และนี่คือสิ่งที่หน่วยความจำจะมีเป็นผลลัพธ์:

การทำงานกับการอ้างอิงและวัตถุ

โปรดทราบว่าtoUpperCase()เมธอด นี้ ไม่ได้เปลี่ยนสตริงที่ถูกเรียกใช้ แต่จะสร้างสตริงใหม่ (วัตถุใหม่) และส่งกลับการอ้างอิงถึงสตริงนั้นแทน

ตัวอย่างที่น่าสนใจยิ่งขึ้น สมมติว่าคุณตัดสินใจส่งสตริงไปยังScannerวัตถุ (เพื่อให้วัตถุนั้นอ่านค่าจากสตริง)

ตัวอย่าง:

String text = "10 20 40 80";
Scanner console = new Scanner(text);
int a = console.nextInt();
int b = console.nextInt();

คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับวิธีScannerการทำงานของชั้นเรียนได้ที่นี่

นี่คือวิธีทั้งหมดจะถูกเก็บไว้ในหน่วยความจำ:

การทำงานกับการอ้างอิงและวัตถุ  คลาสสแกนเนอร์

ในกรณีนี้Stringวัตถุชิ้นเดียวยังคงอยู่ในหน่วยความจำเช่นเดิม เฉพาะการอ้างอิงไปยังวัตถุนั้นเท่านั้นที่จะถูกส่งผ่านและจัดเก็บไว้ในตัวแปร


5. การเปรียบเทียบการอ้างอิงถึงStringวัตถุ

และในที่สุดเราก็มาถึงส่วนที่สนุก: การเปรียบเทียบสตริง

มีตัวดำเนินการสองตัวที่คุณสามารถใช้เพื่อเปรียบเทียบตัวแปรสตริง: ==(เท่ากับ) และ!=(ไม่เท่ากัน) คุณไม่สามารถใช้ตัวดำเนินการ "มากกว่า" "น้อยกว่า" หรือ "มากกว่าหรือเท่ากับ" ได้ — คอมไพเลอร์ไม่อนุญาต

แต่มีความแตกต่างเล็กน้อยที่น่าสนใจที่นี่: อะไรที่เก็บในตัวแปรสตริง ถูกต้อง: ที่อยู่ (อ้างอิง) ถึงวัตถุ และที่อยู่เหล่านี้จะถูกเปรียบเทียบ:

String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase(); 

นี่คือสิ่งที่จะอยู่ในความทรงจำ:

การเปรียบเทียบการอ้างอิงกับวัตถุสตริง

ตัวแปรmessageและtextอ้างถึง (เก็บที่อยู่ของ) วัตถุเดียวกัน แต่ ตัวแปร s1และs2เก็บการอ้างอิงถึงวัตถุที่คล้ายกันมากแต่แตกต่างกัน

และถ้าคุณเปรียบเทียบตัวแปรทั้ง 4 นี้ในโค้ด คุณจะได้ผลลัพธ์ดังนี้

รหัส เอาต์พุตคอนโซล
String text = "Hi";
String message = text;
String s1 = text.toUpperCase();
String s2 = text.toUpperCase();
System.out.println(text == message);
System.out.println(text == s1);
System.out.println(s1 == s2); 


true  // The addresses are equal
false // The addresses are different
false // The addresses are different