Treeset รองรับวิธีการเรียงลำดับสองวิธี: การเรียงลำดับตามธรรมชาติและการเรียงลำดับแบบกำหนดเอง Treeset ใช้การเรียงลำดับตามธรรมชาติตามค่าเริ่มต้น
1. การเรียงลำดับตามธรรมชาติ
Treeset จะเรียกวิธีการเปรียบเทียบ (Object OBJ) ขององค์ประกอบการรวบรวมเพื่อเปรียบเทียบความสัมพันธ์ขนาดระหว่างองค์ประกอบจากนั้นจัดเรียงองค์ประกอบการรวบรวมตามลำดับจากน้อยไปมาก (presponse สำหรับการเปรียบเทียบ: วัตถุทั้งสองมีประเภทเดียวกัน)
Java จัดเตรียมอินเทอร์เฟซที่เปรียบเทียบได้ซึ่งกำหนดวิธีการเปรียบเทียบ (Object OBJ) ซึ่งส่งคืนค่าจำนวนเต็ม เมื่อวัตถุเรียกวิธีการเปรียบเทียบกับวัตถุอื่นเช่น OBJ1.COMPARTO (OBJ2) หากวิธีการส่งคืน 0 นั่นหมายความว่าวัตถุทั้งสองจะเท่ากัน OBJ2; หากวิธีการส่งคืนจำนวนเต็มลบหมายถึง OBJ1 น้อยกว่า OBJ2
คลาส Java ทั่วไปใช้อินเทอร์เฟซที่เปรียบเทียบได้และให้มาตรฐานสำหรับขนาดเปรียบเทียบ คลาสทั่วไปที่ใช้อินเทอร์เฟซที่เปรียบเทียบได้:
หากคุณพยายามที่จะเพิ่มวัตถุลงในชุดต้นไม้คลาสของวัตถุจะต้องใช้อินเตอร์เฟสที่เปรียบเทียบได้
ข้อผิดพลาดจะถูกรายงานในโปรแกรมต่อไปนี้:
Class Err {} Public Class TestTreesEterror {โมฆะสาธารณะคงที่หลัก (String [] args) {Treeset TS = ใหม่ชุดต้นไม้ (); เพิ่ม (ใหม่ err ());ภาพประกอบ:
โปรแกรมข้างต้นพยายามเพิ่มวัตถุ ERR 2 รายการลงในคอลเลกชัน Treeset ของวัตถุ) วิธีการเปรียบเทียบกับองค์ประกอบอื่น ๆ ในคอลเลกชัน - หากคลาสที่เกี่ยวข้องไม่ได้ใช้อินเตอร์เฟสที่เปรียบเทียบได้จะมีการยกระดับ ClassCastException ยิ่งไปกว่านั้นเมื่อพยายามลบองค์ประกอบแรกขององค์ประกอบออกจากชุดต้นไม้ข้อยกเว้น ClassCastException จะยังคงเพิ่มขึ้น
เมื่อเปรียบเทียบวัตถุโดยใช้วิธีการเปรียบเทียบ (Object OBJ) ประเภทของวัตถุเปรียบเทียบ OBJ จะต้องถูกโยนเป็นประเภทเดียวกันเพราะมีเพียงสองอินสแตนซ์ของคลาสเดียวกันเท่านั้นที่สามารถเปรียบเทียบขนาดได้ นั่นคือวัตถุที่เพิ่มเข้ามาในชุดต้นไม้ควรอยู่ในชั้นเรียนเดียวกันมิฉะนั้นจะมีการยกระดับ ClassCastException ตัวอย่างเช่นเมื่อเพิ่มวัตถุสตริงลงในชุดต้นไม้การดำเนินการนี้เป็นเรื่องปกติอย่างสมบูรณ์ เมื่อเพิ่มวัตถุวันที่ที่สอง Treeet จะเรียกวิธีการเปรียบเทียบ (Object OBJ) ของวัตถุเพื่อเปรียบเทียบกับองค์ประกอบอื่น ๆ ในคอลเลกชันและโปรแกรมจะโยนข้อยกเว้นในเวลานี้
ในการเขียนโปรแกรมจริงโปรแกรมเมอร์สามารถกำหนดคลาสของตัวเองเพื่อเพิ่มวัตถุหลายประเภทลงใน Treeset โดยมีเงื่อนไขว่าคลาสที่ผู้ใช้กำหนดใช้จะใช้อินเทอร์เฟซที่เปรียบเทียบได้ . แปลง. อย่างไรก็ตามเมื่อใช้งานข้อมูลการรวบรวมใน TreeSet ข้อยกเว้น ClasscastExceptio จะยังคงเกิดขึ้นสำหรับองค์ประกอบของประเภทต่าง ๆ (คุณจะเข้าใจหลังจากอ่านอย่างระมัดระวัง)
เมื่อวัตถุถูกเพิ่มเข้าไปในคอลเลกชัน Treeet Treeset เรียกใช้วิธีการเปรียบเทียบของวัตถุ (Object OBJ) เพื่อเปรียบเทียบขนาดกับวัตถุอื่น ๆ ในภาชนะแล้วกำหนดตำแหน่งการจัดเก็บตามอัลกอริทึมต้นไม้สีแดงและสีดำ หากมีการเปรียบเทียบวัตถุสองชิ้นอย่างเท่าเทียมกันโดยเปรียบเทียบ (Object OBJ) Treeet จะพิจารณาว่าพวกเขาเก็บตำแหน่งเดียวกัน
สำหรับคอลเลกชันของ Treeset เกณฑ์สำหรับการพิจารณาว่าวัตถุสองชิ้นไม่เท่ากันคือ: วัตถุสองชิ้นกลับเท็จผ่านการเปรียบเทียบวิธี Equals หรือเปรียบเทียบ (Object OBJ) การเปรียบเทียบไม่กลับ 0 - แม้ว่าวัตถุทั้งสองจะเป็นวัตถุเดียวกัน จะถูกประมวลผลเป็นสองวัตถุ
โปรแกรมต่อไปนี้แสดง:
// คลาส z, การเขียนใหม่ของวิธี Equals, กลับมาเป็นเท็จเสมอ, // วิธีการเปรียบเทียบ (Object OBJ) มักจะส่งกลับคลาสจำนวนเต็มบวก z ใช้ {อายุ int; } บูลีนสาธารณะเท่ากับ (Object obj) {return false;} public int compereto (Object obj) {return 1; Z1 = ใหม่ Z (6); Set); การเห็นยังกลายเป็น 9 system.out.println ((z) (set.last ())).โปรแกรมการรันผลลัพธ์:
จริง
[treeset.z@1fb8ee3, treeset.z@1fb8ee3]
9
ภาพประกอบ:
วัตถุเดียวกันจะถูกเพิ่มสองครั้งในโปรแกรมเนื่องจากวิธี Equals () ของวัตถุ Z1 จะส่งคืนเท็จเสมอและวิธีการเปรียบเทียบ (Object OBJ) จะส่งคืน 1 เสมอ ด้วยวิธีนี้ Treeet จะคิดว่าวัตถุ Z1 นั้นแตกต่างจากตัวมันเองดังนั้นเพิ่มวัตถุ Z1 สองชิ้นลงในชุดต้นไม้ องค์ประกอบทั้งสองที่บันทึกโดยวัตถุ Treeet นั้นเป็นองค์ประกอบเดียวกัน ดังนั้นหลังจากปรับเปลี่ยนแอตทริบิวต์อายุขององค์ประกอบแรกในคอลเลกชัน Treeset แอตทริบิวต์อายุขององค์ประกอบสุดท้ายในคอลเล็กชั่น Treeet ก็เปลี่ยนไปเช่นกัน
สรุป : เมื่อคุณต้องการใส่วัตถุลงในชุดต้นไม้และเขียนวิธีการเท่ากับ () ของคลาสที่สอดคล้องกันของวัตถุคุณควรตรวจสอบให้แน่ใจว่าวิธีนี้มีผลลัพธ์ที่สอดคล้องกับวิธีการเปรียบเทียบ (Object OBJ) วัตถุสองชิ้นผ่านเมื่อการเปรียบเทียบวิธีการเท่ากับส่งคืนจริงวัตถุทั้งสองควรส่งคืน 0 โดยเปรียบเทียบวิธีการเปรียบเทียบ (Object OBJ)
หากมีการเปรียบเทียบวัตถุสองชิ้นโดยวิธี Equals แต่วัตถุทั้งสองจะถูกเปรียบเทียบโดยวิธีการเปรียบเทียบ (Object OBJ) และไม่กลับ 0 สิ่งนี้จะทำให้ Treeet ช่วยประหยัดวัตถุทั้งสองในตำแหน่งที่แตกต่างกัน เพิ่มได้สำเร็จซึ่งแตกต่างจากกฎของคอลเลกชันชุดเล็กน้อย
หากวัตถุสองชิ้นส่งคืน 0 โดยเปรียบเทียบวิธีการเปรียบเทียบ (Object OBJ) แต่พวกเขากลับมาเป็นเท็จโดยการเปรียบเทียบวิธีการเท่ากับ: เนื่องจากวัตถุทั้งสองนั้นเปรียบเทียบกับวิธีการเปรียบเทียบ (Object OBJ) อย่างเท่าเทียมกัน สถานที่เดียวกัน แต่จริง ๆ แล้วมันไม่ได้ผล (มิฉะนั้นจะมีวัตถุที่เหลือเพียงชิ้นเดียว) ดังนั้นจึงเป็นเรื่องยากที่จะจัดการ
หากมีการเพิ่มวัตถุที่ไม่แน่นอนลงในชุดต้นไม้และโปรแกรมที่ตามมาจะปรับเปลี่ยนคุณสมบัติของวัตถุที่ไม่แน่นอนทำให้มันเปลี่ยนลำดับขนาดกับวัตถุอื่น ๆ แต่ชุดต้นไม้จะไม่ปรับคำสั่งซื้ออีกครั้งและอาจทำให้มันถูกบันทึกไว้ ในชุดต้นไม้ทั้งสองวัตถุเหล่านี้กลับมาเป็นจริงโดยการเปรียบเทียบวิธี Equals และวิธีการเปรียบเทียบ (Object OBJ) กลับมา 0
โปรแกรมต่อไปนี้แสดง:
คลาส r {int count; if (OBJ Instanceof R) {R R = (R) OBJ; คลาส testhashset2 {โมฆะคงที่หลัก (สตริง [] args) {hashset hs = new hashset (); r (9)); . TITERATOR (); ใน Sequential State System.out.println (HS); -3 r วัตถุ? " + hs.contains (ใหม่ R (-3))); 5)));โปรแกรมการรันผลลัพธ์:
[R (แอตทริบิวต์นับ: -3), r (แอตทริบิวต์นับ: -2), r (แอตทริบิวต์นับ: 5), r (แอตทริบิวต์นับ: 9)]
[R (แอตทริบิวต์นับ: 20), r (แอตทริบิวต์นับ: -2), r (แอตทริบิวต์นับ: 5), r (แอตทริบิวต์นับ: -2)]
[R (แอตทริบิวต์นับ: 20), r (แอตทริบิวต์นับ: -2), r (แอตทริบิวต์นับ: 5), r (แอตทริบิวต์นับ: -2)]
[R (แอตทริบิวต์นับ: 20), R (แอตทริบิวต์นับ: -2), r (แอตทริบิวต์นับ: -2)]
ภาพประกอบ:
วัตถุ R ในโปรแกรมข้างต้นเป็นวิธีการเขียนแบบปกติของวิธี Equals และคลาสวิธีที่เปรียบเทียบได้ คุณจะเห็นว่าผลลัพธ์แรกของโปรแกรมถูกจัดเรียงอย่างเป็นระเบียบ เมื่อคุณสมบัติการนับของวัตถุ R เปลี่ยนผลลัพธ์ผลลัพธ์ของโปรแกรมจะเปลี่ยนแปลงและมีองค์ประกอบที่ซ้ำกัน เมื่อคุณสมบัติขององค์ประกอบตัวแปรในคอลเลกชัน TreeSet มีการเปลี่ยนแปลงเมื่อวัตถุถูกลบในมุมมอง Treeset จะล้มเหลวในการลบ (แม้แต่องค์ประกอบที่เป็นต้นฉบับในคอลเลกชันยังไม่ได้รับการแก้ไข แต่องค์ประกอบที่เท่ากับการแก้ไข องค์ประกอบไม่สามารถลบได้)
เมื่อวัตถุ R ที่มี -2 ไม่มีองค์ประกอบถูกลบ
สรุป: ด้วย HashSet มันจะซับซ้อนมากและผิดพลาดได้ง่ายเมื่อจัดการกับวัตถุเหล่านี้ เพื่อให้โปรแกรมมีความแข็งแกร่งมากขึ้นขอแนะนำให้วางวัตถุที่ไม่เปลี่ยนรูปในคอลเลกชัน Hashset และ Treeset เท่านั้น
2. การเรียงลำดับแบบกำหนดเอง
ชุดต้นไม้ตามธรรมชาติขึ้นอยู่กับขนาดขององค์ประกอบการรวบรวมและชุดต้นไม้จัดเรียงตามลำดับจากน้อยไปมาก หากคุณต้องการใช้การเรียงลำดับที่กำหนดเองเช่นลำดับจากมากไปน้อยคุณสามารถใช้อินเตอร์เฟสเปรียบเทียบ อินเทอร์เฟซนี้มีวิธีการเปรียบเทียบ int (T O1, T O2) ซึ่งใช้เพื่อเปรียบเทียบขนาดของ O1 และ O2
หากคุณต้องการใช้การเรียงลำดับที่กำหนดเองคุณจะต้องจัดเตรียมวัตถุเปรียบเทียบเมื่อสร้างวัตถุคอลเลคชั่นต้นไม้และจัดเตรียมวัตถุเปรียบเทียบเพื่อเชื่อมโยงกับคอลเลกชันของ Treeset และวัตถุเปรียบเทียบมีหน้าที่ในการจัดเรียงตรรกะขององค์ประกอบการรวบรวม
โปรแกรมต่อไปนี้แสดง:
Class M {Int อายุ; Main (String [] args) {treeet ts = treeset ใหม่ (ตัวเปรียบเทียบใหม่ () {public int Compare (Object O1, Object O2) {M M1 = (M) O1; M M2 = (M) O2; if (M1 อายุ> m2.age) {return -1; TS.Add (ใหม่ M (-3));โปรแกรมรันผลลัพธ์:
[M Object (อายุ: 9), M Object (อายุ: 5), M Object (อายุ: -3)]
ภาพประกอบ:
โปรแกรมข้างต้นสร้างวัตถุคลาสภายในที่ไม่ระบุชื่อของอินเทอร์เฟซเปรียบเทียบซึ่งรับผิดชอบในการเรียงลำดับของคอลเลกชัน TS ดังนั้นเมื่อเราเพิ่มวัตถุ M ลงในคอลเลกชัน TS ไม่จำเป็นสำหรับคลาส M ในการใช้อินเทอร์เฟซที่เปรียบเทียบได้เนื่องจากในเวลานี้ Treeet ไม่จำเป็นต้องเปรียบเทียบขนาดผ่านวัตถุ M แต่วัตถุเปรียบเทียบที่เกี่ยวข้องกับ Treeet รับผิดชอบการเรียงลำดับขององค์ประกอบการรวบรวม เมื่อใช้การเรียงลำดับแบบกำหนดเอง Treeset จัดเรียงองค์ประกอบการรวบรวมโดยไม่คำนึงถึงขนาดขององค์ประกอบการรวบรวมเอง แต่วัตถุเปรียบเทียบมีหน้าที่ในการเรียงลำดับกฎการเรียงลำดับขององค์ประกอบการรวบรวม