gpt4 book ai didi

C#/Java : Proper Implementation of CompareTo when Equals tests reference identity

转载 作者:行者123 更新时间:2023-12-01 16:41:16 25 4
gpt4 key购买 nike

我相信这个问题同样适用于 C# 和 Java,因为两者都要求 {c,C}ompareTo 与 {e,E}quals 一致:

假设我希望我的 equals() 方法与引用检查相同,即:

public bool equals(Object o) {
return this == o;
}

在这种情况下,我如何实现compareTo(Object o)(或其通用等效项)?一部分很简单,但我不确定另一部分:

public int compareTo(Object o) {
MyClass other = (MyClass)o;
if (this == other) {
return 0;
} else {
int c = foo.CompareTo(other.foo)
if (c == 0) {
// what here?
} else {
return c;
}
}
}

我不能盲目地返回1或-1,因为解决方案应该遵循compareTo的正常要求。我可以检查所有实例字段,但如果它们都相等,我仍然希望compareTo返回0以外的值。 a.compareTo(b) == -(b.compareTo(a) 应该是正确的),并且只要对象的状态不改变,顺序就应该保持一致。

但是,我并不关心虚拟机调用之间的顺序。这让我觉得我可以使用内存地址之类的东西,如果我能得到它的话。话又说回来,也许这行不通,因为垃圾收集器可能会决定移动我的对象。

hashCode 是另一个想法,但我想要始终唯一的东西,而不仅仅是大部分唯一。

有什么想法吗?

最佳答案

首先,如果您使用的是 Java 5 或更高版本,您应该实现 Comparable<MyClass>而不是普通的旧Comparable ,因此你的compareTo方法应采用 MyClass 类型的参数,不是Object :

public int compareTo(MyClass other) {
if (this == other) {
return 0;
} else {
int c = foo.CompareTo(other.foo)
if (c == 0) {
// what here?
} else {
return c;
}
}
}

就你的问题而言,Josh Bloch 在《Effective Java》(第 3 章,第 12 项)中说道:

The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compare- To(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception if and only if y.compareTo(x) throws an exception.)

这意味着如果上面代码中的 c == 0,则必须返回 0。

这又意味着您可以拥有对象 A 和 B,它们不相等,但它们的比较返回 0。布洛赫先生对此有何看法?

It is strongly recommended, but not strictly required, that (x.compareTo(y) == 0) == (x.equals(y)). Generally speaking, any class that implements the Comparable interface and violates this condition should clearly indicate this fact. The recommended language is “Note: This class has a natural ordering that is inconsistent with equals.”

还有

A class whose compareTo method imposes an order that is inconsistent with equals will still work, but sorted collections containing elements of the class may not obey the general contract of the appropriate collection interfaces (Collection, Set, or Map). This is because the general contracts for these interfaces are defined in terms of the equals method, but sorted collections use the equality test imposed by compareTo in place of equals. It is not a catastrophe if this happens, but it’s something to be aware of.

更新:因此恕我直言,对于您当前的类(class),您无法制作 compareToequals一致。如果您确实需要这个,我认为唯一的方法是引入一个新成员,这将为您的类(class)提供严格的自然顺序。那么当两个对象的所有有意义的字段比较为0时,您仍然可以根据它们的特殊顺序值来决定两个对象的顺序。

这个额外的成员可能是一个实例计数器,或者一个创建时间戳。或者,您可以尝试使用 UUID .

关于C#/Java : Proper Implementation of CompareTo when Equals tests reference identity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2439862/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com