ฉันจะบอกว่าคำตอบเหล่านี้พลาด
โบลชในจาวาที่มีผลบังคับใช้ที่ยอดเยี่ยมและกระชับของเขาได้กล่าวไว้ในข้อ 47 ในหัวข้อ "รู้จักและใช้งานห้องสมุด", "เพื่อสรุปอย่ารวมวงล้อใหม่" และเขาให้เหตุผลที่ชัดเจนหลายประการว่าทำไมไม่
มีคำตอบเล็กน้อยที่นี่ซึ่งแนะนำวิธีการต่างๆจากCollectionUtils
ในห้องสมุด Apache Commons Collections แต่ไม่มีใครเห็นวิธีตอบคำถามที่สวยงามและงดงามที่สุด :
Collection<Object> culprits = CollectionUtils.disjunction( list1, list2 );
if( ! culprits.isEmpty() ){
// ... do something with the culprits, i.e. elements which are not common
}
culprits : Lists
คือองค์ประกอบที่ไม่ตรงกันทั้งสอง กำหนดซึ่งต้นเหตุที่อยู่list1
และที่จะlist2
ค่อนข้างตรงไปตรงมาใช้และCollectionUtils.intersection( list1, culprits )
อย่างไรก็ตามมันมีแนวโน้มที่จะกระจุยในกรณีเช่น {"a", "a", "b"} ด้วย {"a", "b", "b"} ... ยกเว้นว่านี่ไม่ใช่ความล้มเหลวของซอฟต์แวร์ แต่ โดยธรรมชาติของ subtleties / ambiguities ของงานที่ต้องการCollectionUtils.intersection( list2, culprits )
disjunction
คุณสามารถตรวจสอบซอร์สโค้ด (l. 287) ได้เสมอสำหรับงานแบบนี้ตามที่วิศวกรของ Apache ทำขึ้น ข้อดีอย่างหนึ่งของการใช้รหัสคือมันจะได้รับการลองและทดสอบอย่างละเอียดพร้อมกับเคสที่มีจำนวนมากและมีการคาดการณ์และจัดการกับมัน คุณสามารถคัดลอกและปรับแต่งรหัสนี้ไปยังเนื้อหาหัวใจของคุณหากจำเป็น
NB ฉันรู้สึกผิดหวังในตอนแรกว่าไม่มีCollectionUtils
วิธีใดที่จะช่วยให้คุณสามารถกำหนดเวอร์ชันของตัวเองได้มากเกินไปComparator
(เพื่อให้คุณสามารถกำหนดใหม่equals
ให้เหมาะกับวัตถุประสงค์ของคุณ)
แต่จากคอลเล็กชัน 4 4.0 มีคลาสใหม่Equator
ซึ่ง "กำหนดความเท่าเทียมกันระหว่างวัตถุประเภท T" ในการตรวจสอบซอร์สโค้ดของ collection4 CollectionUtils.java พวกเขาดูเหมือนจะใช้สิ่งนี้กับวิธีการบางอย่าง แต่เท่าที่ฉันสามารถทำได้สิ่งนี้ไม่สามารถใช้ได้กับวิธีการที่ด้านบนของไฟล์โดยใช้CardinalityHelper
คลาส ... ซึ่ง รวมและ disjunction
intersection
ฉันเดาว่าคน Apache ยังไม่ได้ทำสิ่งนี้เพราะมันไม่ใช่เรื่องไร้สาระคุณจะต้องสร้างบางสิ่งเช่นคลาส "AbstractEquatingCollection" ซึ่งแทนที่จะใช้องค์ประกอบโดยธรรมชาติequals
และhashCode
วิธีการแทนที่จะใช้สิ่งเหล่านั้น ของEquator
ทุกวิธีการขั้นพื้นฐานเช่นadd
, contains
ฯลฯ NB ในความเป็นจริงเมื่อคุณดูรหัสที่มาAbstractCollection
ไม่ใช้add
หรือไม่ subclasses นามธรรมเช่นAbstractSet
... คุณต้องรอจนกว่าการเรียนคอนกรีตเช่นHashSet
และArrayList
ก่อนที่จะadd
ถูกนำไปใช้ ปวดหัวค่อนข้าง
ในขณะที่ดูพื้นที่นี้ฉันคิดว่า ทางออกชั่วคราวที่เห็นได้ชัดคือการห่อองค์ประกอบทั้งหมดของคุณในคลาส wrapper bespoke ซึ่งใช้equals
และhashCode
ใช้ชนิดของความเสมอภาคที่คุณต้องการ ... จากนั้นจัดการกับCollections
วัตถุ wrapper เหล่านี้