我有一组不可变对象(immutable对象),它们实现了 equals() ,严格比较它们所持有的成员变量。如果成员变量相等,则两个对象是相同的。 hashCodes()
与此一致。
我希望能够根据更宽松的相似性定义来聚合这些对象。我正在考虑为此使用比较器,以便我可以定义一堆临时相似性规则,但 javadoc 指出比较器应该与 equals()
一致。是否可以使用 equals()
打破比较器契约来实现此目的,或者是否有更好的方法/模式/策略来根据某些相似性规则聚合对象?
示例可能包括:
- 位置:如果 LatLng 和地名完全相等,则
equals()
返回 true,但如果 LatLng 在 25m/50m/100m 范围内(无论地名等如何),或者如果仅地名相等,无论 LatLng 如何,则比较器返回 0。 - 日期:如果长毫秒相等,
equals()
返回 true,但如果在同一天/月/年等,则比较器返回 0。 - 字符串:如果
equalsIgnoreCase()
为 true,equals()
返回 true,但比较器可能会删除空格/特殊字符以简化为某种规范形式,然后运行 equals
等。
最佳答案
考虑到“相似性”不是传递操作:如果a与b相似,并且b与c相似,那么a可能不与c相似,我建议不要在这里使用Comparable
/Comparator
,因为它的契约意味着传递性。
适合您需求的自定义界面应该是一个不错的选择:
interface SimilarityComparable<T, D> {
// D - object that represents similarity level
D getSimilarityLevel(T other);
}
但是,由于 Java 泛型的原因,使用这种方法您将无法为同一类型定义多个相似组:
class Location implements SimilarityComparable<Location, Distance>, SimilarityComparable<Location, NameDifference> {
// won't compile - can't use two generic interfaces of the same type simultaneously
}
在这种情况下,您可以回退到比较器:
interface SimilarityComparator<T, D> {
D getSimilarityLevel(T a, T b);
}
class LocationDistanceSimilarityComparator implements SimilarityComparator<Location, Distance> {
...
}
class LocationNameSimilarityComparator implements SimilarityComparator<Location, NameDifference> {
...
}
关于java - 使用比较器聚合相似的对象,而不与 equals() 保持一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31159195/