หากคุณต้องการทราบว่าชุดเท่ากันหรือไม่equals
วิธีการเปิดAbstractSet
จะถูกนำไปใช้โดยประมาณดังนี้:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Collection c = (Collection) o;
if (c.size() != size())
return false;
return containsAll(c);
}
สังเกตว่าจะเพิ่มประสิทธิภาพกรณีทั่วไปอย่างไรโดยที่:
- วัตถุทั้งสองเหมือนกัน
- วัตถุอื่นไม่ได้เป็นชุดเลยและ
- ขนาดทั้งสองชุดแตกต่างกัน
หลังจากนั้นcontainsAll(...)
จะส่งคืนfalse
ทันทีที่พบองค์ประกอบในชุดอื่นที่ไม่อยู่ในชุดนี้ด้วย แต่ถ้าองค์ประกอบทั้งหมดมีอยู่ในทั้งสองชุดก็จะต้องทดสอบองค์ประกอบทั้งหมด
ประสิทธิภาพของกรณีที่เลวร้ายที่สุดจึงเกิดขึ้นเมื่อทั้งสองชุดมีค่าเท่ากัน แต่ไม่ใช่วัตถุเดียวกัน ค่าใช้จ่ายที่เป็นปกติO(N)
หรือขึ้นอยู่กับการดำเนินงานของO(NlogN)
this.containsAll(c)
และคุณจะได้รับประสิทธิภาพในกรณีที่ใกล้เคียงกับที่แย่ที่สุดหากชุดมีขนาดใหญ่และมีองค์ประกอบที่แตกต่างกันเพียงเล็กน้อยเท่านั้น
อัปเดต
หากคุณยินดีที่จะลงทุนเวลาในการใช้งานชุดที่กำหนดเองมีวิธีการที่สามารถปรับปรุงกรณี "เกือบเหมือนกัน" ได้
ความคิดคือการที่คุณต้องไปก่อนคำนวณและแคชแฮสำหรับการตั้งค่าทั้งหมดเพื่อที่คุณจะได้รับค่าแฮชโค้ดของตลาดหลักทรัพย์ฯ O(1)
ในปัจจุบัน จากนั้นคุณสามารถเปรียบเทียบแฮชโค้ดของทั้งสองชุดเป็นการเร่งความเร็ว
คุณจะใช้แฮชโค้ดแบบนั้นได้อย่างไร? ถ้าแฮชโค้ดที่ตั้งไว้คือ:
- ศูนย์สำหรับเซตว่างและ
- XOR ของแฮชโค้ดองค์ประกอบทั้งหมดสำหรับชุดที่ไม่ว่างเปล่า
จากนั้นคุณสามารถอัปเดตแฮชโค้ดที่แคชของชุดได้ในราคาถูกทุกครั้งที่คุณเพิ่มหรือลบองค์ประกอบ ในทั้งสองกรณีคุณเพียงแค่ XOR แฮชโค้ดขององค์ประกอบด้วยแฮชโค้ดชุดปัจจุบัน
แน่นอนว่าสิ่งนี้ถือว่าแฮชโค้ดขององค์ประกอบมีความเสถียรในขณะที่องค์ประกอบเป็นสมาชิกของชุด นอกจากนี้ยังถือว่าฟังก์ชัน hashcode ของคลาสองค์ประกอบให้การแพร่กระจายที่ดี นั่นเป็นเพราะเมื่อแฮชโค้ดทั้งสองชุดเหมือนกันคุณยังคงต้องถอยกลับไปสู่การO(N)
เปรียบเทียบองค์ประกอบทั้งหมด
คุณสามารถนำแนวคิดนี้ไปอีกเล็กน้อย ... อย่างน้อยก็ในทางทฤษฎี
คำเตือน - เป็นการเก็งกำไรอย่างมาก "การทดลองทางความคิด" หากคุณต้องการ
สมมติว่าคลาส set element ของคุณมีวิธีการส่งคืนการตรวจสอบ crypto สำหรับองค์ประกอบ ตอนนี้ใช้การตรวจสอบของชุดโดย XORing การตรวจสอบที่ส่งคืนสำหรับองค์ประกอบ
สิ่งนี้ซื้ออะไรให้เรา?
ดีถ้าเราคิดว่าเล่ห์เหลี่ยมอะไรที่เกิดขึ้นน่าจะเป็นที่ใดสององค์ประกอบชุดที่ไม่เท่ากันมี checksums N-bit เดียวกัน 2 -N และความน่าจะเป็น 2 ชุดที่ไม่เท่ากันมี checksums N-bit เดียวกันนอกจากนี้ยังมี 2 -N ดังนั้นความคิดของฉันคือคุณสามารถใช้equals
เป็น:
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof Set))
return false;
Collection c = (Collection) o;
if (c.size() != size())
return false;
return checksums.equals(c.checksums);
}
ภายใต้สมมติฐานข้างต้นนี้จะให้คำตอบที่ผิดเพียงครั้งเดียวใน 2 -Nครั้ง หากคุณสร้าง N ให้ใหญ่พอ (เช่น 512 บิต) ความน่าจะเป็นของคำตอบที่ผิดจะกลายเป็นเรื่องเล็กน้อย (เช่นประมาณ 10 -150 )
ข้อเสียคือการคำนวณการตรวจสอบการเข้ารหัสลับสำหรับองค์ประกอบนั้นมีราคาแพงมากโดยเฉพาะเมื่อจำนวนบิตเพิ่มขึ้น ดังนั้นคุณต้องมีกลไกที่มีประสิทธิภาพในการบันทึกเช็คซัม และนั่นอาจเป็นปัญหาได้
และข้อเสียอีกประการหนึ่งคือความน่าจะเป็นของข้อผิดพลาดที่ไม่ใช่ศูนย์ ประการหนึ่งคือความน่าจะเป็นอาจไม่สามารถยอมรับได้ไม่ว่าความน่าจะเป็นจะน้อยเพียงใดก็ตาม (แต่ถ้าเป็นเช่นนั้น ... คุณจะจัดการกับกรณีที่รังสีคอสมิกพลิกบิตวิกฤตได้อย่างไรหรือถ้ามันพลิกบิตเดียวกันในสองกรณีของระบบซ้ำซ้อนพร้อมกัน)