我有一组不可变对象实现equals(),严格比较它们持有的成员变量。如果成员变量相等,则两个对象是相同的。 hashCodes()与此相符。
我希望能够根据相似性的宽松定义聚合这些对象。我正在考虑使用比较器,以便我可以定义一组特殊的相似性规则,但是javadoc声明比较器应该与equals一致。可以用equals()打破比较器契约来实现这一点,还是有一些更好的方法/模式/策略来根据一些相似性规则聚合对象?
示例可能包括:
非常感谢, RIZ
答案 0 :(得分:0)
考虑到“相似性”不是传递操作:如果 a 类似于 b , b 类似于 c ,然后 a 可能 与 c 类似,我建议不要使用Comparable
/ {{ 1}}这里,因为它的契约意味着传递性。
适合您需求的自定义界面应该是一个不错的选择:
Comparator
然而,使用这种方法,由于Java泛型,您将无法为同一类型定义多个相似性组:
interface SimilarityComparable<T, D> {
// D - object that represents similarity level
D getSimilarityLevel(T other);
}
在这种情况下,您可以回退到比较器:
class Location implements SimilarityComparable<Location, Distance>, SimilarityComparable<Location, NameDifference> {
// won't compile - can't use two generic interfaces of the same type simultaneously
}
答案 1 :(得分:0)
答案取决于您打算如何使用比较。
但是,我同意@ user3707125,在任何情况下都不要为此目的实现Comparable
。您无法控制哪些代码将使用Comparable
函数进行必须遵循所定义规则的比较。
在某些情况下,必须使用Comparator
,例如,如果您使用标准Java API库对对象进行排序或过滤。如果是这种情况,那么您使用Comparator
仍然非常安全,因为您可以控制使用Comparator
的位置,以及使用更严格equals()
的位置。您只需要注意,如果您的宽松比较不符合标准合同,那么排序和过滤操作将产生同样放松和不一致的结果。
如果您不必使用Comparator
,请不要。你可以自由地定义自己的方法和接口,以任何你喜欢的方式做任何你想做的事情。自己敲门!