对集合使用hashCode()和equals()的多个替代

时间:2013-06-12 05:29:33

标签: java set equals hashcode

假设我有一个简单的POJO类Class1,它有两个int类型的字段。

我已经实现了它的hashCode()和equals()方法来处理这两个字段,以便将类的实例放入一个集合中。

到目前为止一切顺利。

现在,我希望有一个不同的集合,如果第一个字段相等,则认为Class1的实例相等,使得相等条件变弱。我甚至可能想要另一个只考虑第二个字段作为检查相等性的字符集。

有可能吗?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:5)

可以在提供仅检查您感兴趣的字段的自定义TreeSet时使用Comparator

但请注意,严格来说,TreeSet这样的Set不再是“正确的”equal(),因为它实际上会忽略对象的Set方法:

  

请注意,如果要正确实现Comparable接口,则由集合维护的排序(无论是否提供显式比较器)必须与equals 一致。 (有关与equals 一致的精确定义,请参阅ComparatorSet。)这是因为equals接口是根据{{1操作,但是TreeSet实例使用其compareTo(或compare)方法执行所有元素比较,因此从这个方法看,两个被认为相等的元素是设定,平等。集合的行为即使其排序与equals不一致也是明确定义的;它只是没有遵守Set接口的一般合同。

答案 1 :(得分:3)

标准Java库不支持此功能。

而且(令人惊讶的是)Apache Commons Collections或Guava库中似乎没有支持此类的MapSet类。

如果你看起来足够努力,可能还有其他的库来支持这个。

或者,您可以编写自己的...从标准HashMap代码开始。


一种廉价而又开朗的替代方法是为您的元素类型创建一个轻量级的包装类,它将大多数方法委托给包装类,并为原始方法提供不同的equals / hashcode对。这样做有一个小的运行时间惩罚......但值得考虑。

Joachim的建议也很好,除非你的套装可能特别大。对于正确实现的哈希表,{TreeSetO(logN)进行了O(1)次查找。)