2013-03-29 65 views
0

我的团队正在处理的代码有几个类,其中equalshashCode未在类层次结构中定义。我们想实现Comparable这样compareToequals一致使用hashCode,就像这样:当equals()和hashCode()未定义时,应如何实现Comparable?

class MyClass implements Comparable<MyClass> 
{ 
    private String myProperty; 
    // Other properties, etc. 
    .... 

    public int compareTo(MyClass obj) { 
     // Natural ordering comparisons 
     ... 
     // Reach here if natural ordering properties are equivalent 
     return new Integer(this.hashCode()).compareTo(new Integer(obj.hashCode()); 
    } 
} 

这被认为是实现Comparable的有效手段?使用我应该知道的默认实现hashCode是否有任何缺陷?

UPDATE:我们追求的行为如下:

  1. 类的属性首先相比,自然排序,我们定义。
  2. 如果两个对象的给定属性是等价的,我们继续下一步。
  3. 如果所有属性都是相同的,只有在this.equals(obj)的情况下我们才返回0。
+4

对于具有相同值的对象,内部'hashCode()'可能不会给你相同的结果,所以最好定义你自己的值。 –

+2

这是所有关于你想比较你的对象的标准。 – sp00m

+1

我通常更喜欢Comparable的内联匿名定义,但我认为如果您需要始终在任何地方使用相同的排序,那么将该实现放入您的域对象是完全可以接受的。然而,就像@HunterMcMillen所说的那样,hashCode并不是真正用来比较的东西。哈希可以重新使用。你最好比较自己想要的部分。 – CodeChimp

回答

0

不,这不是实现Comparable的有效方法。因为,假设您在equals方法内的MyClass两个不同对象的所有自然排序比较都成立,那么当两个对象的散列码相比较时,它将返回false。这是因为在这种情况下hashcode方法的Object类将被默认调用(因为你没有提供你自己的哈希码方法),这对于不同的对象将是不同的。因此,无论所有自然排序比较是否为true,MyClass的两个对象都不会相同。

0

是的,这是一种有效的方法。显然你想要一个固定的顺序,对于其他值相等的对象(我是对的吗?你没有在这里解释你的目标与哈希码的用法)。 我会做的唯一的事情是在你的compareTo方法中复制Integer.compareTo()的java代码,所以你不必为每次比较都创建2个整数。

+0

谢谢 - 我希望我用我的更新澄清了我的'hashCode()'的用法。 – akaplan

+0

on“3.我们只返回0如果this.equals(obj)。” - >然后使用equals,而不是哈希码,否则你可能会有一个罕见的哈希码冲突(两个对象返回相同的哈希)。另一件事:如果他们不相同,该怎么办?返回负面或正面,为什么? – bluevoid

+0

感谢@bluevoid提醒我碰撞的可能性。只有当“equals”成立时才返回0才有意义。如果不是,那么为了满足'Comparable'合约,如果'!a.equals(b)'必须返回-1,如果'!b.equals(a)'则返回1。返回默认的-1或1会使'compareTo'违反传递性要求。 – akaplan

相关问题