ฉันมีสองชุด A และ B ประเภทเดียวกัน
ฉันต้องหาว่า A มีองค์ประกอบใด ๆ จากเซต B หรือไม่
อะไรจะเป็นวิธีที่ดีที่สุดในการทำสิ่งนั้นโดยไม่ทำซ้ำในฉาก? ห้องสมุดตลาดหลักทรัพย์ได้contains(object)และแต่ไม่containsAll(collection)containsAny(collection)
ฉันมีสองชุด A และ B ประเภทเดียวกัน
ฉันต้องหาว่า A มีองค์ประกอบใด ๆ จากเซต B หรือไม่
อะไรจะเป็นวิธีที่ดีที่สุดในการทำสิ่งนั้นโดยไม่ทำซ้ำในฉาก? ห้องสมุดตลาดหลักทรัพย์ได้contains(object)และแต่ไม่containsAll(collection)containsAny(collection)
คำตอบ:
จะไม่Collections.disjoint(A, B)ทำงานเหรอ จากเอกสาร:
ส่งคืน
trueถ้าคอลเล็กชันที่ระบุสองรายการไม่มีองค์ประกอบที่เหมือนกัน
ดังนั้นเมธอดจะส่งคืนfalseหากคอลเล็กชันมีองค์ประกอบทั่วไปใด ๆ
anyMatchจะสตรีมองค์ประกอบทั้งหมดจากsetAและโทรหาsetB.contains()พวกเขาทั้งหมด หากส่งคืน "ความจริง" สำหรับองค์ประกอบใด ๆ นิพจน์โดยรวมจะประเมินค่าเป็นจริง หวังว่านี่จะช่วยได้
วิธีที่ดีในการดำเนินการ containsAny สำหรับชุดที่ใช้ฝรั่งSets.intersection ()
containsAnyจะคืนค่า a booleanดังนั้นการโทรจึงดูเหมือนว่า:
Sets.intersection(set1, set2).isEmpty()
สิ่งนี้จะคืนค่าเป็นจริงถ้าชุดนั้นไม่ต่อเนื่องหรือเป็นเท็จ ความซับซ้อนของเวลาในการทำเช่นนี้น่าจะดีกว่า keepAll เล็กน้อยเนื่องจากคุณไม่จำเป็นต้องทำการโคลนใด ๆ เพื่อหลีกเลี่ยงการแก้ไขชุดต้นฉบับของคุณ
Apache CollectionUtils.containsAny()คอมมอนส์มีวิธีการ
ฉันใช้ org.apache.commons.collections.CollectionUtils
CollectionUtils.containsAny(someCollection1, someCollection2)
นั้นคือทั้งหมด! ผลตอบแทนจริงถ้าอย่างน้อยหนึ่งองค์ประกอบอยู่ในคอลเลกชันทั้งสอง
ใช้งานง่ายและชื่อของฟังก์ชั่นมีการชี้นำมากกว่า
ใช้retainAll()ในชุดอินเตอร์เฟส วิธีนี้จะให้จุดตัดขององค์ประกอบทั่วไปในทั้งสองชุด ดูเอกสาร API สำหรับข้อมูลเพิ่มเติม
retainAllอาจไม่ช่วยได้ การใช้งานในAbstractCollectioniterates
O(1)เวลาทำงานในกรณีที่ดีที่สุดในขณะที่retainAllจะมีบางสิ่งบางอย่างตามเส้นของO(N)(มันจะขึ้นอยู่กับขนาดเพียง 1 ชุด) เวลาทำงานที่ดีที่สุด
ฉันขอแนะนำให้สร้าง a HashMapจาก set A จากนั้นวนซ้ำผ่าน set B และตรวจสอบว่าองค์ประกอบของ B ใด ๆ อยู่ใน A สิ่งนี้จะทำงานในO(|A|+|B|)เวลา (เนื่องจากไม่มีการชน) ในขณะที่retainAll(Collection<?> c)ต้องทำงานในO(|A|*|B|)เวลา
มีวิธีคร่าวๆเล็กน้อยในการทำเช่นนั้น ถ้าหากว่าชุด A มีองค์ประกอบของ B บางอย่างมากกว่าการโทร
A.removeAll(B)
จะแก้ไขชุด A ในสถานการณ์นี้ removeAll จะส่งคืนจริง (ตามที่ระบุไว้ที่removeAll docs ) แต่คุณอาจไม่ต้องการแก้ไขชุด A ดังนั้นคุณอาจคิดว่าจะทำสำเนาเหมือนอย่างนี้:
new HashSet(A).removeAll(B)
และค่าส่งคืนจะเป็นจริงหากเซตไม่ชัดเจนนั่นคือมีจุดตัดที่ไม่ว่างเปล่า
คุณสามารถใช้retainAllวิธีการและได้รับการจุดตัดของสองชุดของคุณ
retainAllจำเป็นต้องทำสำเนาชุดต้นฉบับ จากนั้นก็จะมีประสิทธิภาพมากขึ้นในการใช้งานHashSetตามข้อเสนอแนะZéychin