我不确定以下代码是否能确保Comparator的Javadoc中给出的所有条件。
class TotalOrder<T> implements Comparator<T> {
public boolean compare(T o1, T o2) {
if (o1 == o2 || equal(o1, o2)) return 0;
int h1 = System.identityHashCode(o1);
int h2 = System.identityHashCode(o2);
if (h1 != h2) {
return h1 < h2 ? -1 : 1;
}
// equals returned false but identity hash code was same, assume o1 == o2
return 0;
}
boolean equal(Object o1, Object o2) {
return o1 == null ? o2 == null : o1.equals(o2);
}
}
上面的代码是否会对任何类的所有实例施加总排序,即使该类没有实现Comparable?
答案 0 :(得分:2)
http://gafter.blogspot.com/2007/03/compact-object-comparator.html
这正是我所寻找的。 p>
答案 1 :(得分:2)
嘿,看看我找到了什么!http://gafter.blogspot.com/2007/03/compact-object-comparator.html
哦,是的,我忘记了IdentityHashMap(仅限Java 6及更高版本)。只需要注意释放比较器。
答案 2 :(得分:1)
你在评论中回答:
等于返回false但标识哈希码相同,假设为o1 == o2
不幸的是你无法想象。大部分时间都会起作用,但在某些例外情况下,它不会。你什么时候都不知道。出现这种情况时,例如,它会导致在TreeSet中丢失实例。
答案 3 :(得分:1)
我不认为这样做,因为没有达到这个条款:
最后,实现者必须确保x.compareTo(y)== 0意味着所有z的sgn(x.compareTo(z))== sgn(y.compareTo(z))。
由于equal(o1,o2)取决于o1的equals实现,因此逻辑上相等的两个对象(由equals确定)仍然具有两个不同的identityHashCodes。
因此,在将它们与第三个对象(z)进行比较时,它们最终可能会为compareTo产生不同的值。
有意义吗?
答案 4 :(得分:1)
当发生哈希冲突时,如果它到达最后return 0
行,则应该引发异常。我确实有一个问题:你在哈希上做了一个总排序,我猜这很好,但是不应该传递一些函数来定义一个Lexicographical命令吗?
int h1 = System.identityHashCode(o1);
int h2 = System.identityHashCode(o2);
if (h1 != h2) {
return h1 < h2 ? -1 : 1;
}
我可以想象你将对象作为一个形成实数的两个整数的元组。但是你不会得到正确的顺序,因为你只是对对象的哈希。如果哈希是你的意思,这完全取决于你,但对我来说,这没有多大意义。
答案 5 :(得分:0)
我不确定System.identityHashCode(Object)
。这几乎是 == 的用途。您可能更愿意使用Object.hashCode()
- 它更与Object.equals(Object)
并行。
答案 6 :(得分:0)
我同意这不是理想的,因此评论。有什么建议吗?
我认为现在有办法可以解决这个问题,因为你无法访问唯一可以区分两个实例的东西:它们在内存中的地址。所以我只有一个建议:重新考虑你需要在Java中进行一般的总订购流程: - )