เทียบเคียงได้
เปรียบเทียบได้คืออินเทอร์เฟซการเรียงลำดับ
หากคลาสใช้อินเทอร์เฟซที่เปรียบเทียบได้นั่นหมายถึง "คลาสนี้รองรับการเรียงลำดับ" เนื่องจากคลาสที่ใช้การเรียงลำดับการสนับสนุนอินเทอร์เฟซที่เปรียบเทียบได้สมมติว่าตอนนี้มี "รายการ (หรืออาร์เรย์) ของวัตถุของคลาสที่ใช้อินเทอร์เฟซที่เปรียบเทียบได้" รายการรายการ (หรืออาร์เรย์) สามารถเรียงลำดับได้โดยคอลเลกชัน
นอกจากนี้ "วัตถุของคลาสที่ใช้อินเทอร์เฟซที่เปรียบเทียบได้" สามารถใช้เป็นคีย์ใน "แผนที่ที่สั่งซื้อ (เช่น treemap)" หรือองค์ประกอบใน "ชุดที่สั่งซื้อ (treeet)" โดยไม่ต้องระบุตัวเปรียบเทียบ
อินเทอร์เฟซที่เปรียบเทียบได้มีเพียงฟังก์ชั่นเดียวและคำจำกัดความของมันมีดังนี้:
แพ็คเกจ java.lang; นำเข้า java.util.*; อินเทอร์เฟซสาธารณะเปรียบเทียบได้ <t> {public int compereto (t o);} คำอธิบาย: สมมติว่าเรา "เปรียบเทียบขนาดของ x และ y" ผ่าน x.compareto (y) หากคุณส่งคืน "จำนวนลบ" มันหมายถึง "x เล็กกว่า y"; หากคุณส่งคืน "ศูนย์" มันหมายถึง "x เท่ากับ y"; หากคุณส่งคืน "จำนวนบวก" มันหมายถึง "x มากกว่า y"
อินเทอร์เฟซที่เปรียบเทียบได้นั้นเป็นเรื่องทั่วไปดังนั้นวัตถุที่ใช้การเปรียบเทียบได้ประกาศว่าสามารถเปรียบเทียบประเภทใดได้บ้าง (โดยทั่วไปนี่คือประเภทของวัตถุเอง แต่บางครั้งก็อาจเป็นคลาสแม่ด้วย)
อินเทอร์เฟซสาธารณะเทียบได้ {public boolean compereto (อื่น ๆ ); -
ดังนั้นอินเทอร์เฟซที่เปรียบเทียบได้มีพารามิเตอร์ประเภท T ซึ่งเป็นประเภทของวัตถุที่คลาสที่ใช้การเปรียบเทียบสามารถเปรียบเทียบได้ ซึ่งหมายความว่าหากคุณกำหนดคลาสที่ใช้เปรียบเทียบได้เช่นสตริงคุณต้องประกาศไม่เพียง แต่คลาสที่รองรับการเปรียบเทียบเท่านั้น
สตริงคลาสสาธารณะใช้การเปรียบเทียบ {... }
ตอนนี้ลองพิจารณาการใช้วิธี Binary Max () คุณต้องการที่จะยอมรับพารามิเตอร์สองชนิดของประเภทเดียวกันทั้งคู่เปรียบได้และเปรียบได้กับกันและกัน โชคดีที่มันค่อนข้างใช้งานง่ายหากคุณใช้วิธีการทั่วไปและพารามิเตอร์ประเภทที่ จำกัด :
สาธารณะคงที่> t สูงสุด (t t1, t t2) {ถ้า (t1.compareto (t2)> 0) ส่งคืน t1; อื่นกลับ t2; -
ในตัวอย่างนี้คุณกำหนดวิธีการทั่วไปที่ถูกสร้างขึ้นในประเภท T และคุณ จำกัด การขยายประเภท (การใช้งาน) พารามิเตอร์ทั้งสองจะต้องเป็นประเภท T ซึ่งหมายความว่าพวกเขาเป็นประเภทเดียวกันการเปรียบเทียบการเปรียบเทียบและเปรียบได้กับกันและกัน ง่าย!
ยิ่งไปกว่านั้นคอมไพเลอร์จะใช้การใช้เหตุผลประเภทเพื่อกำหนดค่าของ t หมายถึงอะไรเมื่อเรียกว่าสูงสุด () ดังนั้นจึงไม่จำเป็นต้องระบุ T เลยการโทรต่อไปนี้จะใช้งานได้:
สตริง s = สูงสุด ("moo", "เปลือก");คอมไพเลอร์จะคำนวณว่าค่าที่กำหนดไว้ล่วงหน้าของ T คือสตริงดังนั้นจะทำการรวบรวมและตรวจสอบประเภท แต่ถ้าคุณพยายามเรียก Max () พร้อมอาร์กิวเมนต์ไปยังคลาส X ที่ไม่สามารถใช้งานได้เปรียบเทียบคอมไพเลอร์จะไม่อนุญาต
เครื่องเปรียบเทียบ
ตัวเปรียบเทียบคืออินเทอร์เฟซเปรียบเทียบ
หากเราต้องการควบคุมลำดับของคลาสที่แน่นอนซึ่งไม่สนับสนุนการเรียงลำดับ (นั่นคือมันไม่ได้ใช้อินเทอร์เฟซที่เปรียบเทียบได้); จากนั้นเราสามารถสร้าง "ตัวเปรียบเทียบคลาสนี้" เพื่อจัดเรียง "ตัวเปรียบเทียบ" นี้จำเป็นต้องใช้อินเตอร์เฟสเปรียบเทียบเท่านั้น
นั่นคือเราสามารถสร้างตัวเปรียบเทียบใหม่โดย "การใช้คลาสเปรียบเทียบ" จากนั้นเรียงลำดับคลาสผ่านตัวเปรียบเทียบ
อินเทอร์เฟซเปรียบเทียบมีเพียงสองฟังก์ชั่นและคำจำกัดความของมันมีดังนี้:
แพ็คเกจ java.util; ตัวเปรียบเทียบอินเตอร์เฟสสาธารณะ <t> {int Compare (T O1, T O2); บูลีนเท่ากับ (Object obj);} ภาพประกอบ:
1. หากคลาสต้องการใช้งานอินเตอร์เฟสเปรียบเทียบ: จะต้องใช้ฟังก์ชันเปรียบเทียบ (T O1, T O2) แต่อาจไม่ใช้ฟังก์ชัน Equals (Object OBJ)
ทำไมเราไม่สามารถใช้ฟังก์ชัน Equals (Object OBJ) ได้? เนื่องจากโดยค่าเริ่มต้น Equals (Object OBJ) ได้ถูกนำมาใช้ คลาสทั้งหมดใน Java ได้รับการสืบทอดจาก Java.lang.Object และฟังก์ชัน Equals (Object OBJ) ถูกนำมาใช้ใน Object.java; ดังนั้นคลาสอื่น ๆ ทั้งหมดจะเทียบเท่ากับการใช้ฟังก์ชั่นนี้
2. การเปรียบเทียบ (T O1, T O2) คือ "เปรียบเทียบขนาดของ O1 และ O2" การกลับ "จำนวนลบ" หมายถึง "O1 มีขนาดเล็กกว่า O2"; การกลับมา "ศูนย์" ความหมาย "O1 เท่ากับ O2"; การกลับมา "จำนวนบวก" หมายถึง "O1 มากกว่า O2"
เครื่องเปรียบเทียบและเปรียบเทียบได้
เปรียบเทียบได้คืออินเทอร์เฟซการเรียงลำดับ หากคลาสใช้อินเทอร์เฟซที่เปรียบเทียบได้นั่นหมายถึง "คลาสนี้รองรับการเรียงลำดับ"
ตัวเปรียบเทียบเป็นตัวเปรียบเทียบ หากเราต้องการควบคุมลำดับของคลาสที่แน่นอนเราสามารถสร้าง "ตัวเปรียบเทียบของคลาสนี้" เพื่อเรียงลำดับ
ไม่ยากที่จะพบว่าการเปรียบเทียบนั้นเทียบเท่ากับ "ตัวเปรียบเทียบภายใน" ในขณะที่ตัวเปรียบเทียบเทียบเท่ากับ "ตัวเปรียบเทียบภายนอก"
เราใช้โปรแกรมทดสอบเพื่อแสดงอินเทอร์เฟซทั้งสองนี้ ซอร์สโค้ดมีดังนี้:
นำเข้า java.util.*; นำเข้า Java.lang.comparable;/*** @desc Program ระหว่าง "เปรียบเทียบ" และ "เปรียบเทียบได้" * (01) "เปรียบเทียบได้" * มันเป็นอินเทอร์เฟซการเรียงลำดับที่มีฟังก์ชั่นเดียวเท่านั้น compereto () * คลาสใช้อินเทอร์เฟซที่เปรียบเทียบได้ซึ่งหมายถึง "คลาสนั้นรองรับการเรียงลำดับ" ซึ่งสามารถเรียงลำดับได้โดยตรงผ่านอาร์เรย์ Sort () หรือคอลเลกชัน SORT () * (02) "ตัวเปรียบเทียบ" * เป็นอินเตอร์เฟสเปรียบเทียบรวมถึงสองฟังก์ชั่น: เปรียบเทียบ () และ equals () * คลาสใช้อินเทอร์เฟซเปรียบเทียบจากนั้นเป็น "ตัวเปรียบเทียบ" คลาสอื่น ๆ สามารถจัดเรียงตามตัวเปรียบเทียบ * * เพื่อรวม: เปรียบเทียบได้เป็นตัวเปรียบเทียบภายในในขณะที่ตัวเปรียบเทียบเป็นตัวเปรียบเทียบภายนอก * คลาสเองใช้ตัวเปรียบเทียบที่เปรียบเทียบได้ซึ่งหมายความว่ามันรองรับการเรียงลำดับ; หากไม่สามารถใช้งานได้เปรียบเทียบตัวเองก็สามารถเรียงลำดับผ่านตัวเปรียบเทียบตัวเปรียบเทียบภายนอก */คลาสสาธารณะ comparComparatorAndComparableTest {โมฆะคงที่สาธารณะหลัก (สตริง [] args) {// สร้าง arrayList ใหม่ (อาร์เรย์แบบไดนามิก) arrayList <person> list = new ArrayList <Person> (); // เพิ่มวัตถุใน arraylist list.add (บุคคลใหม่ ("CCC", 20)); list.add (บุคคลใหม่ ("AAA", 30)); list.add (บุคคลใหม่ ("BBB", 10)); list.add (บุคคลใหม่ ("ddd", 40)); // พิมพ์ลำดับต้นฉบับของรายการ system.out.printf ("การเรียงลำดับต้นฉบับรายการ:%s/n", รายการ); // เรียงลำดับรายการ // ที่นี่มันจะถูกจัดเรียงตาม "อินเทอร์เฟซ <string> ที่เปรียบเทียบได้ที่ใช้โดยบุคคล" นั่นคือเรียงลำดับตาม "ชื่อ", collections.sort (รายการ); System.out.printf ("การเรียงชื่อ, รายการ:%s/n", รายการ); // เรียงลำดับรายการผ่าน "ตัวเปรียบเทียบ (ascageComparator)" // วิธีการเรียงลำดับของ ascageComparator คือ: เรียงลำดับตามลำดับจากน้อยไปมากของคอลเลกชัน "อายุ" System.out.printf ("ASC (อายุ) เรียงลำดับรายการ:%s/n", รายการ); // เรียงลำดับรายการผ่าน "ตัวเปรียบเทียบ (descageComparator)" // วิธีการเรียงลำดับของ descageComparator คือ: เรียงลำดับตามลำดับจากมากไปน้อยของคอลเลกชัน "อายุ" sorts (รายการ, descageComparator ใหม่ ()); System.out.printf ("Desc (อายุ) เรียงลำดับรายการ:%s/n", รายการ); // ตรวจสอบว่าทั้งสองคนมีความเท่าเทียมกัน (); } /*** @DESC ทดสอบว่าทั้งสองคนมีค่าเท่ากันหรือไม่ * เนื่องจากบุคคลใช้ฟังก์ชั่น Equals (): หากอายุและชื่อของบุคคลทั้งสองเท่ากันคนสองคนจะถูกพิจารณาว่าเท่ากัน * ดังนั้นที่นี่ P1 และ P2 เท่ากัน * * TODO: ถ้าฟังก์ชั่น Equals () ในบุคคลถูกลบออกแล้ว P1 จะไม่เท่ากับ P2 */ Void Void Testequals () {Person P1 = บุคคลใหม่ ("EEE", 100); บุคคล p2 = บุคคลใหม่ ("eee", 100); if (p1.equals (p2)) {system.out.printf (" %s เท่ากับ %s/n", p1, p2); } else {system.out.printf (" %s ไม่เท่ากับ %s/n", p1, p2); }} /*** @desc person class * บุคคลใช้อินเทอร์เฟซที่เปรียบเทียบได้ซึ่งหมายความว่าบุคคลนั้นสนับสนุนการเรียงลำดับ*/ บุคคลชั้นเรียนแบบคงที่ส่วนตัวใช้ <person> {อายุ int; ชื่อสตริง; บุคคลสาธารณะ (ชื่อสตริงอายุ int) {this.name = ชื่อ; this.age = อายุ; } สตริงสาธารณะ getName () {ชื่อคืน; } public int getage () {return Age; } Public String ToString () {return name + " -" + อายุ; } / *** เปรียบเทียบว่าสองคนมีค่าเท่ากัน: ถ้าชื่อและอายุของพวกเขาเท่ากันพวกเขาจะถือว่าเท่ากัน* / บูลีนเท่ากับ (บุคคลบุคคล) {ถ้า (this.age == person.age && this.name == person.name) กลับมาจริง; กลับเท็จ; } /*** @DESC ใช้อินเทอร์เฟซของ "เปรียบเทียบ <String>" นั่นคือการเขียนฟังก์ชันเปรียบเทียบ <t t> * นี่คือการเปรียบเทียบโดย "ชื่อของบุคคล"*/ @Override สาธารณะ int compereto (บุคคลบุคคล) {return name.Compareto (person.name); // return this.name - person.name; }} / *** @desc AscageComparator comparator* มันคือ "ตัวเปรียบเทียบจากอายุของบุคคล"* / คลาสคงที่คลาสคงที่ AscageComparator ใช้ตัวเปรียบเทียบ <person> {@Override สาธารณะ int เปรียบเทียบ (บุคคล P1, บุคคล p2) {return p1.getage () - p2.getage () }} / *** @DESC DESCAGECOMPARATOR COMPALATOR* มันคือ "ตัวเปรียบเทียบจากอายุของบุคคล"* / คลาสคงที่คลาสคงที่ DescageComparator ใช้ตัวเปรียบเทียบ <person> {@Override public int เปรียบเทียบ (บุคคล P1, บุคคล P2) {return p2.getage () - ต่อไปนี้เป็นคำอธิบายของโปรแกรมนี้
1. คำจำกัดความของคลาส Person ดังนี้:
ชั้นเรียนแบบคงที่ส่วนตัวใช้การเปรียบเทียบ <person> {อายุ int; ชื่อสตริง; ... /*** @DESC ใช้อินเทอร์เฟซของ "เทียบเท่า <string>" นั่นคือแทนที่ฟังก์ชันเปรียบเทียบ <t t> * นี่คือการเปรียบเทียบโดย "ชื่อของบุคคล"*/ @Override สาธารณะ int compereto (บุคคลบุคคล) {return name.Compareto (person.name); // return this.name - person.name; - ภาพประกอบ:
(1) ชั้นเรียนบุคคลเป็นตัวแทนของบุคคล มีสองคุณลักษณะในคลาส Persong: อายุ (อายุ) และชื่อ "ชื่อบุคคล"
(2) คลาสบุคคลใช้อินเทอร์เฟซที่เปรียบเทียบได้ดังนั้นจึงสามารถเรียงลำดับได้
2. ใน Main () เราสร้างอาร์เรย์รายการของบุคคล (รายการ) ดังนี้:
// สร้าง arraylist ใหม่ (อาร์เรย์แบบไดนามิก) ArrayList <person> list = new ArrayList <person> (); // เพิ่มวัตถุใน arraylist list.add (ใหม่ ("ccc", 20)); list.add (บุคคลใหม่ ("AAA", 30)); list.add 3. ถัดไปเราพิมพ์องค์ประกอบทั้งหมดของรายการ ดังนี้:
// พิมพ์ลำดับต้นฉบับของรายการ system.out.printf ("การเรียงลำดับต้นฉบับรายการ:%s/n", รายการ); 4. จากนั้นเราเรียงลำดับรายการผ่านฟังก์ชั่นการเรียงลำดับ () ของคอลเลกชัน
เนื่องจากบุคคลใช้อินเทอร์เฟซที่เปรียบเทียบได้เมื่อเรียงลำดับผ่านการเรียงลำดับ () มันจะถูกเรียงลำดับตามวิธีการเรียงลำดับที่สนับสนุนโดยบุคคลนั่นคือกฎที่กำหนดโดยการเปรียบเทียบ (บุคคลบุคคล) ดังนี้:
// เรียงลำดับรายการ // ที่นี่เราจะเรียงลำดับตามอินเตอร์เฟส "เปรียบเทียบ <String> ที่ใช้โดยบุคคล" นั่นคือการเรียงลำดับตามคอลเลกชัน "ชื่อ" sorts (รายการ); System.out.printf ("การเรียงชื่อ, รายการ:%s/n", รายการ); 5. เปรียบเทียบและเปรียบเทียบ
เรากำหนดตัวเปรียบเทียบสองตัวคือ AscageComparator และ DescageComparator เพื่อขึ้นและผู้ที่มีลำดับต่ำกว่าตามลำดับ
6.AscageComparator เปรียบเทียบมันเรียงลำดับบุคคลตามลำดับจากน้อยไปหามาก รหัสมีดังนี้:
/*** @DESC AscageComparator comparator* มันคือ "ตัวเปรียบเทียบอายุของบุคคล"*/คลาสคงที่ระดับคงที่ Ascagecomparator ใช้ตัวเปรียบเทียบ <person> {@Override int Compare (Person P1, Person P2) {return p1.getage () - p2.getage (); - 7. descageComparator เปรียบเทียบมันเรียงลำดับบุคคลตามลำดับจากมากไปน้อยตามอายุ รหัสมีดังนี้:
/*** @DESC DESCAGECOMPARATOR COMPALATOR* มันคือ "ตัวเปรียบเทียบอายุของบุคคล"*/คลาสคงที่คลาสคงที่ DescageComparator ใช้ตัวเปรียบเทียบ <person> {@Override Public Int Compare (Person P1, Person P2) {return p2.getage () - P1.getage (); - 8. เรียกใช้โปรแกรมเป็นผลให้ผลลัพธ์มีดังนี้:
การเรียงลำดับต้นฉบับ, รายการ: [CCC - 20, AAA - 30, BBB - 10, DDD - 40] การเรียงลำดับชื่อ, รายการ: [AAA - 30, BBB - 10, CCC - 20, DDD - 40] ASC (อายุ) รายการ: [BBB - 10, CCC - 20, AAA - 30, DDD - 40] BBB - 10] EEE - 100 EEE เท่ากัน - 100