我会说这些答案错过了一个窍门。
Bloch在他的必不可少的,精妙的,简洁的有效Java中说,在项目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
}
罪魁祸首:即两者都不共有的元素Lists
。确定哪些罪犯属于list1
,哪些list2
是相对简单的使用CollectionUtils.intersection( list1, culprits )
和CollectionUtils.intersection( list2, culprits )
。
但是,在诸如{“ a”,“ a”,“ b”} disjunction
和{“ a”,“ b”,“ b”}的情况下,它趋于崩溃……除非这不是软件故障,而是所需任务的微妙/模糊性的本质所固有的。
您始终可以检查源代码(l。287)以完成由Apache工程师生产的此类任务。使用他们的代码的好处之一是,将对它进行彻底的尝试和测试,并预期和处理许多边缘情况和陷阱。如果需要,您可以将此代码复制并调整到您的内心。
注意:最初,我很失望,没有一种CollectionUtils
方法提供重载版本,使您可以强制使用自己的版本Comparator
(因此您可以重新定义equals
以适合您的目的)。
但是从collections4 4.0开始,有一个新类,Equator
“确定类型T的对象之间的相等性”。在检查collections4 CollectionUtils.java的源代码时,他们似乎正在将此方法与某些方法一起使用,但是据我所知,这不适用于文件顶部使用CardinalityHelper
类的方法。包括disjunction
和intersection
。
我猜想Apache人还没有解决这个问题,因为它是不平凡的:您将不得不创建类似“ AbstractEquatingCollection”类的类,该类不使用其元素的内在equals
和hashCode
方法,而必须使用那些的Equator
所有基本方法,如add
,contains
等NB其实当你看到的源代码,AbstractCollection
不执行add
,也没有它的抽象子类,如AbstractSet
...你必须要等到具体的类,如HashSet
和ArrayList
前add
被实施。很头疼。
同时,我想同时观察这个空间。显而易见的临时解决方案是将您的所有元素包装在一个定制的包装器类中,该类使用equals
并hashCode
实现您想要的等式...然后操纵Collections
这些包装器对象。