具有自定义相等标准的Java HashSet?

我正在寻找类似于Java TreeSet在实例化时接收自定义比较器的能力,所以我不需要使用对象的默认相等(和哈希码)标准。

我能想到的最接近的是将我的对象包装在一个私有的自定义类中,但这看起来很糟糕:(这在编程时最终会成为一种反复出现的主题,所以我想知道是否已有可供我们使用的东西。也许在公共图书馆?

谢谢

不,你已经找到了你应该使用的解决方案。

即使对于TreeSet ,也不赞成使用与equals不兼容的比较标准:

请注意,如果有序集合要正确实现Set接口,则由有序集合维护的排序(无论是否提供显式比较器)必须与equals一致。

(我不知道Apache Commons,但是Guava 明确 拒绝了对此类事情的请求。)

你是对的,当你想使用任何TreesTreeMapTreeSet )时,你添加的对象必须实现Comparable

对于原始类型,Java已经为您解决了这个问题。
对于自定义对象,您有3种可能性:

  1. 您的一个对象已经具有基本类型的唯一ID或已实现compareTo()的类型(如String )然后将此字段用于compareTo,如果其他值的值对于相等并不重要。 (但是equals()也必须只使用这一个字段)

  2. 使用Apache的EqualsBuilder :这适用于reflection,并不是最快的解决方案

  3. 自己编写,阅读一些教程如何做到这一点:例如:

Josh Bloch:有效的第2版

但是不要忘记equals()compareTo()必须兼容(和hashCode() ),这样你就不会违反equals契约。 (合同本身不太容易理解,但如果你把其中一个等同于教程,它就会变得清晰。)

或者忘掉所有,并使用HashSetHashMap

有几个第三方集合框架允许自定义相等逻辑。 这非常适合覆盖无法更改源的对象的相等性。

  • 特罗韦

Trove的地图/集支持使用自定义散列策略,允许您根据输入数据的特征调整集合。 此function还允许您在无法覆盖Object.hashCode()时定义散列函数。

  • HE-collections

要实现这一点,任何需要标准修正的类型都必须实现HE-Collection接口EqualsAndHashCorrection。 此接口定义方法hashCodeInHeCollection()和equalsInHeCollection(Object),用于更正不正确的已实现方法hashCode()和equals(Object)。