我不确定以下代码是否能确保 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 ?

有帮助吗?

解决方案

嘿,看看我发现了什么!

http://gafter.blogspot.com/2007/03/compact-object-comparator.html

哦,是的,我忘记了 IdentityHashMap(仅限 Java 6 及更高版本)。只需要注意释放比较器即可。

其他提示

嘿,看看我发现了什么!

http://gafter.blogspot.com/2007/03/compact-object-comparator.html

这正是我一直在寻找的。

您在评论中回答:

equals 返回 false 但身份哈希码相同,假设 o1 == o2

不幸的是你不能这样假设。大多数情况下,这会起作用,但在某些特殊情况下,它不会起作用。而且你不知道什么时候。当出现这种情况时,例如会导致 TreeSet 中的实例丢失。

我认为不会,因为不满足此条款:

最后,实现者必须确保对于所有 z,x.compareTo(y)==0 意味着 sgn(x.compareTo(z)) == sgn(y.compareTo(z))。

由于 equal(o1, o2) 取决于 o1 的 equals 实现,因此逻辑上相等(由 equals 确定)的两个对象仍然具有两个不同的identityHashCode。

因此,当将它们与第三个对象 (z) 进行比较时,它们最终可能会产生不同的compareTo 值。

合理?

如果到达最后,您可能应该引发异常 return 0 行——当哈希冲突发生时。不过我确实有一个问题:您正在对哈希进行总排序,我认为这很好,但是不应该将某些函数传递给它来定义词典顺序吗?

    int h1 = System.identityHashCode(o1);
    int h2 = System.identityHashCode(o2);
    if (h1 != h2) {
        return h1 < h2 ? -1 : 1;
    }

我可以想象您将对象作为形成实数的两个整数的元组。但你不会得到正确的顺序,因为你只获取对象的哈希值。如果散列是您的意思,这完全取决于您,但对我来说,这没有多大意义。

我同意这并不理想,因此发表评论。有什么建议么?

我认为现在有一种方法可以解决这个问题,因为您无法访问唯一可以区分两个实例的东西:他们在内存中的地址。所以我只有一个建议:重新考虑您对 Java 中通用总订购流程的需求:-)

我不太确定 System.identityHashCode(Object). 。差不多就是这样 == 是用来。您可能更想使用 Object.hashCode() - 它更平行于 Object.equals(Object).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top