java - 使用比较器聚合相似的对象,而不与 equals() 保持一致

标签 java equals

我有一组不可变对象(immutable对象),它们实现了 equals() ,严格比较它们所持有的成员变量。如果成员变量相等,则两个对象是相同的。 hashCodes() 与此一致。

我希望能够根据更宽松的相似性定义来聚合这些对象。我正在考虑为此使用比较器,以便我可以定义一堆临时相似性规则,但 javadoc 指出比较器应该与 equals() 一致。是否可以使用 equals() 打破比较器契约来实现此目的,或者是否有更好的方法/模式/策略来根据某些相似性规则聚合对象?

示例可能包括:

  • 位置:如果 LatLng 和地名完全相等,则 equals() 返回 true,但如果 LatLng 在 25m/50m/100m 范围内(无论地名等如何),或者如果仅地名相等,无论 LatLng 如何,则比较器返回 0。
  • 日期:如果长毫秒相等,equals() 返回 true,但如果在同一天/月/年等,则比较器返回 0。
  • 字符串:如果 equalsIgnoreCase() 为 true,equals() 返回 true,但比较器可能会删除空格/特殊字符以简化为某种规范形式,然后运行 ​​equals 等。

最佳答案

考虑到“相似性”不是传递操作:如果ab相似,并且bc相似,那么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/

相关文章:

java - 使用 Websocket 连接 stomp 和 ActiveMQ

java - 如何使用java访问selenium中具有相同类名的第二个元素

java - 自定义 AsyncProcessor 中的 Camel Producer 模板

java - 当 hashcode() 实现返回常量值时,为什么哈希表会退化为链表?

java - 自定义对象作为映射键

c# - 为什么哈希表和字典不使用 Equals() 方法而不是 GetHashCode 在 .NET 中进行键比较?

java - Junit 预期异常失败

java - Camel CXF 抛出 Part{example.com} 参数应该是 X 类型而不是 Y 类型

java - 如何使用 boolean equals(object o) 方法并调用该方法所应用的对象?

java - 如何继续在数组上提供方法,直到它等于其他数组