5

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

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

到目前为止,一切都很好。

现在,我想要一个不同的集合,如果第一个字段是 equal ,它认为 Class1 的实例是相等的,从而使相等条件更弱。我什至可能想要另一组仅将第二个字段视为检查相等性的字段。

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

4

2 回答 2

5

可以TreeSet通过在提供Comparator仅检查您感兴趣的字段的自定义时使用 a 来获得该效果。

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

请注意,如果要正确实现接口,集合维护的顺序(无论是否提供显式比较器)必须与 equals 一致。Set(有关与 equals 一致的精确定义,请参见Comparableor 。)这是因为接口是根据操作定义的,但实例使用其(or ) 方法执行所有元素比较,因此两个元素被视为相等从集合的角度来看,方法是相等的。一个集合的行为是明确定义的,即使它的顺序与equals不一致;它只是不遵守接口的一般合同。ComparatorSetequalsTreeSetcompareTocompareSet

于 2013-06-12T05:34:54.243 回答
3

标准 Java 库不支持这一点。

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

如果您足够努力,可能还有其他库可以支持这一点。

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


一个廉价而愉快的替代方案是为您的元素类型创建一个轻量级的包装类,它将大多数方法委托给被包装的类,并提供与原始类型不同的equals/hashcode对。这样做会有一点运行时损失……但值得考虑。

Joachim 的建议也很好,除非你的系列可能特别大。(与正确实现的哈希表相比TreeSet具有查找功能。)O(logN)O(1)

于 2013-06-12T06:03:19.753 回答