ปัญหาเปรียบเทียบใน Java เป็นพื้นฐานและง่ายต่อการสับสน วันนี้ฉันจะสรุปและจัดระเบียบสรุปรายละเอียดเพิ่มเติมและการจัดเรียงข้อผิดพลาดไม่กี่คะแนนโดยหวังว่ามันจะเป็นประโยชน์สำหรับการศึกษาและการสัมภาษณ์ของทุกคน
1. ความแตกต่างระหว่าง == และเท่ากับ ()
ก่อนอื่นเราจำเป็นต้องทราบความแตกต่างระหว่าง == และ Equals () เครื่องหมาย == จะถูกเปรียบเทียบกับค่าที่อยู่เสมอ สำหรับชนิดข้อมูลพื้นฐาน == การเปรียบเทียบเป็นจริงไม่ว่าค่าตัวแปรจะเท่ากันในขณะที่สำหรับชนิดข้อมูลอ้างอิงค่าที่อยู่จะถูกเปรียบเทียบ สิ่งที่คุณต้องให้ความสนใจเป็นพิเศษกับที่นี่คือประเภทสตริงซึ่งง่ายต่อการได้รับ == และง่ายต่อการทำผิดพลาด วิธี Equals () เป็นวิธีการในคลาสวัตถุ เรารู้ว่าคลาสทั้งหมดใน Java จะสืบทอดคลาส Object โดยค่าเริ่มต้นดังนั้นวัตถุคลาสจะมีวิธี Equals () วิธี Equals () ในคลาสวัตถุแสดงในรูปด้านล่าง:
ดังที่เห็นได้จากซอร์สโค้ดเลเยอร์พื้นฐานของวิธี Equals () ในคลาสวัตถุยังใช้ == ดังนั้นจึงเป็นค่าที่อยู่ ดังนั้นหากเราต้องการใช้วิธี Equals () สำหรับการเปรียบเทียบอื่น ๆ เราจำเป็นต้องแทนที่วิธี Equals ()
2. ประเภทข้อมูลพื้นฐานและประเภทบรรจุภัณฑ์
เราทุกคนรู้ว่าไบต์, สั้น, int, ยาว, บูลีน, ถ่าน, double และ float เป็นชนิดข้อมูลพื้นฐานและตัวแปรที่พวกเขาประกาศจะถูกเก็บไว้ในหน่วยความจำสแต็ก ตัวแปรที่กำหนดโดยประเภทบรรจุภัณฑ์ที่สอดคล้องกัน (ไบต์, สั้น, จำนวนเต็ม, ยาว, บูลีน, ตัวละคร, คู่) มีอยู่ในหน่วยความจำฮีป สำหรับประเภทข้อมูลพื้นฐานการเปรียบเทียบของพวกเขานั้นค่อนข้างง่ายนั่นคือใช้ == เพื่อตรวจสอบว่าพวกเขามีความเท่าเทียมกันและใช้ <,>, <=,> = เพื่อเปรียบเทียบขนาด แต่สำหรับประเภทบรรจุภัณฑ์มันแตกต่างกันเล็กน้อย
ก่อนอื่นสำหรับการพิจารณาว่าเท่ากันหรือไม่ให้ดูผลลัพธ์การดำเนินการของรหัสต่อไปนี้:
Package DailyTest; Import org.junit.test;/*** สรุปการเปรียบเทียบใน java* @author yrr*/คลาสสาธารณะ Javacomparetest {/*** การตัดสินประเภทจำนวนเต็มเท่ากับ*/@test โมฆะสาธารณะทดสอบ 01 () {int n3 = 48; System.out.println ("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- N8); System.out.println ("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- - System.out.println (n1.intvalue () == n2.intvalue (); N6); nullPointException}/*** การตัดสินประเภทยาวเท่ากับ*/@Test โมฆะสาธารณะ test02 () {// หมายเหตุที่นี่ว่าเมื่อใช้คำจำกัดความยาว l หรือ l ไม่จำเป็น แต่เมื่อใช้ยาวมิฉะนั้นจะมีการรายงานข้อผิดพลาด // เพิ่มในการก่อสร้างเพื่อระบุความแตกต่างที่ยาว N3 = 48L; System.out.println ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ - N1); System.out.println ("---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- System.out.println (N4 == N5); // true // เมื่อใช้วิธี long.intvalue () คุณต้องให้ความสนใจเพื่อตรวจสอบว่าเป็นโมฆะเพื่อป้องกัน nullpointexception}}}สำหรับผลการดำเนินการข้างต้นมีคำอธิบายต่อไปนี้:
ก่อนอื่นสำหรับวิธีการใหม่เราประกาศจำนวนเต็มหรือวัตถุยาว เนื่องจากวัตถุใหม่เปิดช่องว่างในกองแม้ว่าค่าของทั้งสองจะเหมือนกันสำหรับ == ค่าที่อยู่จะถูกเปรียบเทียบดังนั้นจึงจะส่งคืนเท็จ สำหรับคลาส wrapper ของชนิดข้อมูลพื้นฐานวิธีการ Equals () ได้รับการเขียนใหม่และขนาดตัวเลขจะถูกเปรียบเทียบดังนั้นวิธี Equals () สามารถใช้เพื่อตัดสินตามขนาดตัวเลข เกี่ยวกับปัญหาของการเปรียบเทียบตัวแปรจำนวนเต็มกับตัวแปร int เราจะพบว่าค่าการเปรียบเทียบนั้นขึ้นอยู่กับขนาดตัวเลข นี่เป็นเพราะเมื่อเปรียบเทียบประเภทจำนวนเต็มจะไม่ถูกบ็อกซ์โดยอัตโนมัติและแปลงเป็นประเภท int คำอธิบายของสามคะแนนแรกใช้กับบรรจุภัณฑ์ทั้งหมด สำหรับวิธีการกำหนดโดยตรงตัวแปรจำนวนเต็มทั้งสองที่มีค่า 48 จะถูกตัดสินว่าเป็นจริงโดยเครื่องหมาย == แต่เมื่อค่าคือ 128 มันเป็นเท็จ นี่เป็นเพราะที่ด้านล่างสำหรับจำนวนเต็ม N1 = 48;, วิธีการกำหนดโดยตรงจริง ๆ เรียกวิธีจำนวนเต็ม value () เราสามารถดูสั้น ๆ ที่ซอร์สโค้ดของเมธอด Integer.Value () ดังแสดงในรูปด้านล่าง:
เราจะเห็นว่ามีการตัดสินที่นี่ เมื่ออินพุตฉันอยู่ในช่วง [-128, 127] มันจะถูกส่งคืนโดยตรงจากอาร์เรย์ IntegerCache ดังนั้นสำหรับค่าในช่วงนี้ค่าที่อยู่ที่สอดคล้องกับอาร์เรย์นี้จะถูกส่งคืนดังนั้นการใช้เครื่องหมาย == เพื่อตัดสินจริงจะถูกส่งคืน สิ่งที่ไม่ได้อยู่ในช่วงนี้คือวัตถุที่ใหม่ดังนั้นจะส่งคืนเท็จ ข้อสรุปนี้เป็นจริงสำหรับประเภทไบต์สั้นจำนวนเต็มและประเภทยาว (ถ้าคุณสนใจคุณสามารถตรวจสอบซอร์สโค้ดของวิธีการที่สอดคล้องกัน ()) เนื่องจากขอบเขตของประเภทไบต์คือ [-128, 127] ดังนั้นสำหรับประเภทไบต์โดยใช้ == ไม่แตกต่างจากเท่ากับ ()
สำหรับการเปรียบเทียบขนาดไม่มีปัญหาในการใช้>, <, <=,> =, และพวกเขาจะไม่ถูกบ็อกซ์โดยอัตโนมัติ แต่เรามักจะแนะนำให้ใช้สองวิธีต่อไปนี้ในการเปรียบเทียบขนาด:
เรียกเมธอด xxxvalue () เพื่อแปลงเป็นชนิดข้อมูลพื้นฐานสำหรับการเปรียบเทียบ ในคลาส wrapper วิธีการเปรียบเทียบ () ถูกเขียนใหม่ โดยการดูที่ซอร์สโค้ด compereto () คุณจะเห็นได้ว่าในความเป็นจริงการใช้งานพื้นฐานจะถูกแปลงเป็นประเภทข้อมูลพื้นฐานที่สอดคล้องกันโดยการยกเลิกกล่องโดยอัตโนมัติแล้วเปรียบเทียบ
2. การเปรียบเทียบวัตถุ Java
ด้วยการแนะนำข้างต้นมันง่ายกว่าที่จะเปรียบเทียบวัตถุ หลักการเหมือนกัน
1. การเปรียบเทียบประเภทสตริง
ควรสังเกตว่าประเภทสตริงไม่สามารถใช้โดยตรง>, <=,> = และ <และจะรายงานข้อยกเว้นการรวบรวม
Package DailyTest; Import org.junit.test;/*** สรุปการเปรียบเทียบใน java* @author yrr*/คลาสสาธารณะ Javacomparetest {@test โมฆะสาธารณะ test03 () {สตริง S1 = สตริงใหม่ ("123"); สตริง s2 = สตริงใหม่ ("123"); System.out.println (S1 == S2); // false system.out.println (s1.equals (S2)); สตริง s3 = "234"; สตริง s4 = "234"; System.out.println (S3 == S4); // true system.out.println (s3.equals (S4)); // true //system.out.println(S1 <= S3); // ตัวดำเนินการ <ไม่ได้กำหนดไว้สำหรับประเภทอาร์กิวเมนต์ java.lang.string, java.lang.string System.out.println (S1.Compareto (S3) <0); //จริง }}2. การเปรียบเทียบวัตถุคลาส
บทสรุปของวัตถุคลาสนั้นเหมือนกัน แต่เมื่อเทียบกับชนิดข้อมูลพื้นฐานและประเภทสตริงมันค่อนข้างซับซ้อนกว่าเล็กน้อย
ตามกฎบางอย่างเพื่อตรวจสอบว่าวัตถุทั้งสองมีค่าเท่ากันหรือไม่วิธี Equals () จะต้องมีการเขียนใหม่ในคลาสที่ตัดสิน รหัสตัวอย่างมีดังนี้:
Package DailyTest; Import org.junit.test;/*** สรุปการเปรียบเทียบใน java* @author yrr*/คลาสสาธารณะ Javacomparetest {@test โมฆะสาธารณะ test04 () {บุคคล p1 = บุคคลใหม่ ("yrr", 18); บุคคล P2 = บุคคลใหม่ ("YRR", 18); System.out.println (P1 == P2); // false system.out.println (p2.equals (P1)); // true}} บุคคลในคลาส {ชื่อสตริงส่วนตัว; อายุจำนวนเต็มส่วนตัว บุคคลสาธารณะ () {} บุคคลสาธารณะ (ชื่อสตริงอายุจำนวนเต็ม) {this.name = name; this.age = อายุ; } สตริงสาธารณะ getName () {ชื่อคืน; } Public Integer Getage () {return Age; } @Override บูลีนสาธารณะเท่ากับ (Object obj) {person person = (บุคคล) obj; return name.equals (person.getName ()) && age.equals (person.getage ()); -และถ้าคุณต้องการเปรียบเทียบขนาดของวัตถุสองชิ้น (นี่เป็นคำถามสัมภาษณ์ทั่วไป) มีสองวิธี:
คลาสที่เปรียบเทียบได้ใช้อินเทอร์เฟซที่เปรียบเทียบได้และแทนที่วิธีการเปรียบเทียบ () เพื่อกำหนดคลาสที่ใช้อินเตอร์เฟสเปรียบเทียบหรือใช้คลาสภายในเพื่อแทนที่วิธีการเปรียบเทียบ (): เดิมถูกกำหนดไว้ในคลาสที่เปรียบเทียบได้ในขณะที่หลังถูกกำหนดนอกคลาสที่เปรียบเทียบได้ ด้วยความแตกต่างนี้ข้อดีและข้อเสียของทั้งสองก็ชัดเจนเช่นกัน อดีตนั้นง่าย แต่ต้องมีการปรับเปลี่ยนคลาสเปรียบเทียบในขณะที่หลังไม่จำเป็นต้องแก้ไขรหัสต้นฉบับซึ่งมีความยืดหยุ่นมากขึ้น
วิธีแรกรหัสตัวอย่างมีดังนี้:
Package DailyTest; Import org.junit.test;/*** สรุปการเปรียบเทียบใน java* @author yrr*/คลาสสาธารณะ Javacomparetest {@test โมฆะสาธารณะทดสอบ 5 () {บุคคล P1 = บุคคลใหม่ ("YRR", 18); บุคคล p2 = บุคคลใหม่ ("wx", 19); System.out.println (P1.Compareto (P2) <0); }} คนในชั้นเรียนใช้การเปรียบเทียบ <person> {ชื่อสตริงส่วนตัว; อายุจำนวนเต็มส่วนตัว บุคคลสาธารณะ () {} บุคคลสาธารณะ (ชื่อสตริงอายุจำนวนเต็ม) {this.name = name; this.age = อายุ; } Public Integer Getage () {return Age; } @Override public int compereto (บุคคล o) {return this.getage () - o.getage (); -วิธีที่สองรหัสตัวอย่างมีดังนี้:
แพ็คเกจเปรียบเทียบ; นำเข้า java.util.arrays; นำเข้า java.util.comparator; คลาสสาธารณะ MyComparator {โมฆะสาธารณะคงที่หลัก (สตริง [] args) {ผู้ใช้ [] ผู้ใช้ = ผู้ใช้ใหม่ [] {ผู้ใช้ใหม่ ("U1001", 25), ผู้ใช้ใหม่ ("U1002", 20), ผู้ใช้ใหม่ array.sort (ผู้ใช้, ตัวเปรียบเทียบใหม่ <user> () {@Override สาธารณะ int เปรียบเทียบ (ผู้ใช้ O1, ผู้ใช้ O2) {return o1.getage () - o2.getage ();}}); สำหรับ (int i = 0; i <users.length; i ++) {ผู้ใช้ผู้ใช้ = ผู้ใช้ [i]; System.out.println (user.getId () + "" + user.getage ()); }}} ผู้ใช้คลาส {รหัสส่วนตัว ID; อายุ int ส่วนตัว; ผู้ใช้สาธารณะ (รหัสสตริงอายุ int) {this.id = id; this.age = อายุ; } public int getage () {return Age; } การตั้งค่าโมฆะสาธารณะ (อายุ int) {this.age = อายุ; } สตริงสาธารณะ getId () {return id; } โมฆะสาธารณะ setId (รหัสสตริง) {this.id = id; -ข้างต้นเป็นเนื้อหาที่เกี่ยวข้องของคำถามเปรียบเทียบ Java ที่ฉันได้บอกคุณในครั้งนี้ หากคุณมีคำถามอื่น ๆ คุณสามารถพูดคุยกันในพื้นที่แสดงความคิดเห็นด้านล่าง ขอบคุณสำหรับการสนับสนุน