【发布时间】:2012-09-20 14:40:35
【问题描述】:
考虑一个具有可比较(与 equals 一致)和不可比较字段(我不知道它是否覆盖 Object#equals 的类)的类。
应比较类的实例,其中结果顺序应与 equals 一致,即如果两个字段相等(根据 Object#equals)并与可比较字段的顺序一致,则返回 0。我使用System.identityHashCode 涵盖了这些要求未涵盖的大多数情况(具有相同可比性但其他值不同的实例的顺序是任意的),但不确定这是否是最佳方法。
public class MyClass implements Comparable<MyClass> {
private Integer intField;
private Object nonCompField;
public int compareTo(MyClass other) {
int intFieldComp = this.intField.compareTo(other.intField);
if (intFieldComp != 0)
return intFieldComp;
if (this.nonCompField.equals(other.nonCompField))
return 0;
// ...and now? My current approach:
if (Systems.identityHashCode(this.nonCompField) < Systems.identityHashCode(other.nonCompField))
return -1;
else
return 1;
}
}
我在这里看到两个问题:
- 如果两个对象的
Systems.identityHashCode相同,则每个对象都大于另一个对象。 (这会发生吗?) - 据我了解
Systems.identityHashCode的作用,具有相同intField值和不同nonCompField值的实例的顺序在程序运行之间不必保持一致。
正确吗?还有更多问题吗?最重要的是,有没有办法解决这个问题?
【问题讨论】:
-
为什么要比较这样的对象,又为什么要比较的对象包括明确不可比较的字段?
-
@LouisWasserman 在依赖于内部排序的数据结构中使用它,例如
TreeMap。 -
这并没有真正解决问题。你为什么想要这样的事情,例如在
TreeMap?你能解释一下你实际上在现实世界中试图做什么来激发这个问题吗? -
@LouisWasserman 我在一个更大的代码库中遇到了一个类,它有一个比较数字字段的比较器,如果这些字段相等且不可比较字段不相等,则返回 1。我试图修复它,但意识到即使我的上述方法也不起作用,因为该类用于类似于
TreeSet的排序数据结构,但实际上依赖于违反比较器的对称性。我记得以前在其他地方使用过上述方法,但现在我想我也可以一起使用(排序的)List和HashMap,而不是那里的一个 TreeMap。