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

时间:2013-02-14 17:19:46

标签: java set hashset

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

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

由于

3 个答案:

答案 0 :(得分:14)

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

即使对于TreeSet,使用与equals不兼容的比较条件也是frowned upon

  

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

(我不知道Apache Commons,但是Guava specifically rejected要求这类事情。)

答案 1 :(得分:3)

您是对的,当您想要使用TreesTreeMapTreeSet)中的任何一个时,您添加的对象必须实现Comparable。 / p>

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

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

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

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

  4.   

    Josh Bloch:有效的java第二版

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

    或者忘掉这一切,并使用HashSetHashMap

答案 2 :(得分:3)

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

  

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

  

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