我正在寻找类似于Java TreeSet在实例化时接收自定义比较器的能力,所以我不需要使用对象的默认相等(和哈希码)标准。
我能想到的最接近的是将我的对象包装在一个私人自定义类中,但这似乎是hacky :(这在编程时最终成为一种反复出现的主题,所以我想知道是否已经有了我们可以使用的东西使用。也许在公共图书馆?
由于
答案 0 :(得分:14)
不,你已经找到了你应该使用的解决方案。
即使对于TreeSet
,使用与equals
不兼容的比较条件也是frowned upon:
请注意,如果有序集合要正确实现Set接口,则由有序集合维护的排序(无论是否提供显式比较器)必须与equals一致。
(我不知道Apache Commons,但是Guava specifically rejected要求这类事情。)
答案 1 :(得分:3)
您是对的,当您想要使用Trees
(TreeMap
,TreeSet
)中的任何一个时,您添加的对象必须实现Comparable
。 / p>
对于原始类型,Java已经为您解决了这个问题
对于自定义对象,您有3种可能性:
您的一个对象已经具有基本类型的唯一ID或已实现compareTo()
的类型(如String
)
然后将此字段用于compareTo,如果其他字段的值对于相等性不重要。
(但是equals()
也必须只使用这一个字段)
使用Apache的EqualsBuilder
:
这适用于反射,并不是最快的解决方案
自己编写,阅读一些教程如何做到这一点:例如:
Josh Bloch:有效的java第二版
但请不要忘记equals()
和compareTo()
必须兼容(以及hashCode()
),这样您就不会违反平等合同。 (合同本身不太容易理解,但如果你把其中一个等同于教程,它就会变得清晰。)
或者忘掉这一切,并使用HashSet
,HashMap
。
答案 2 :(得分:3)
有一些第三方集合框架允许自定义相等逻辑。这非常适合覆盖无法更改源的对象的相等性。
Trove的地图/集支持使用自定义散列策略, 允许您根据输入的特征调整集合 数据。此功能还允许您定义散列函数 不可能覆盖Object.hashCode()。
要实现这一点,任何需要标准修正的类型都必须 实现HE-Collection接口EqualsAndHashCorrection。这个 interface定义方法hashCodeInHeCollection()和 equalsInHeCollection(Object),用作校正 不正确的实现方法hashCode()和equals(Object)。