在JVM堆中,是否可以有多个具有相同哈希码的对象?

时间:2009-12-03 18:00:47

标签: java hash jvm

根据标题,堆上是否可以有多个具有相同哈希码的对象?

10 个答案:

答案 0 :(得分:22)

public class MyObject {
    @Override
    public int hashCode() {
        return 42;
    }

    public static void main(String[] args) {
        MyObject obj1 = new MyObject();
        MyObject obj2 = new MyObject(); // Ta-da!
    }
}

对于不那么轻率的回答,请考虑hashCode Javadocs

  

hashCode的一般合约是:

     
      
  • ...(剪辑)......
  •   
  • 如果两个对象根据equals(Object)方法相等,则对两个对象中的每一个调用hashCode方法必须生成相同的整数结果。
  •   

答案 1 :(得分:6)

,因为您可以拥有任意数量的具有相同hashCode的对象。例如,以下代码没有实习字符串,显示了这一事实:

String foo = new String("dfa");
String bar = new String("dfa");
assert foo != bar; // yields false, two distinct objects (references)
assert foo.hashCode() == bar.hashCode(); // yields true

答案 2 :(得分:4)

琐碎的证明: hashCode返回一个32位整数。

分配2 ^ 32 + 1个对象。 (可能需要一个64位的VM和大量的RAM!;-))

现在你的hashCode方法,无论多么聪明,都必须发生冲突。

答案 3 :(得分:3)

关于哈希码:是的,它们差不多,但不是很独特。 :)这取决于实施/理论它们是多么独特。

但是如果我们谈论JVM,我们首先必须讨论你的意思是什么样的哈希码。

如果你谈论f.e使用的hashCode()方法的结果。通过HashMap,答案是:它取决于您的实现和JVM中的对象数量 在自我实现的hashCode()方法中解决此冲突是您的选择,计划和知识。

如果你谈论System.identityHashCode(obj)方法的结果,那就有点不同了。此实现不会调用您的hashCode()方法。并且实现并不是唯一的 - 但它几乎是唯一的,就像许多其他不同的哈希函数一样。 :)

public class MyObject {
    @Override
    public int hashCode() {
        return 42;
    }

    public static void main(String[] args) {
        MyObject obj1 = new MyObject();
        MyObject obj2 = new MyObject(); // Ta-da!

        final int obj1Hash = System.identityHashCode( obj1 );
        final int obj2Hash = System.identityHashCode( obj2 );

        if( obj1Hash == obj2Hash ) throw new IllegalStateException();
    }
}

在这个例子中,你会得到不同的哈希值,在大多数情况下它们是不同的,但不一定是唯一的......

祝你好运!

答案 4 :(得分:1)

是的,hashcode是一种标准算法,它试图避免重复('碰撞')但不保证它。

此外,它是可重写的,因此您可以编写自己的实现,为每个对象生成相同的哈希码;至于你为什么要这样做我却没有答案。 : - )

答案 5 :(得分:1)

你可以,但这通常不是一个好主意。上面几次提到的例子:

public int hashCode(){
     return 1;
}

在hashCode()规范下完全有效。但是,这样做会将HashMap变为链接列表,从而显着降低性能。因此,您通常希望实现hashCode,以便将值返回为唯一值。

但实际上,许多实现都会发生冲突。以此为例:

public class OrderedPair{
     private int x;
     private int y;

     public int hashCode(){
          int prime = 31;
          int result=x;
          result =result*prime+y;
          return result; 
     }

     public boolean equals(){...}
}

这是hashCode()的一个非常标准的实现(事实上,这非常接近在IDEA和Eclipse中自动生成的输出),但它可能有很多冲突:x = 1,y = 0并且x = 0,y = 1将适用于初学者。编写良好的hashCode()实现的想法是没有足够的冲突来保证您的性能不会受到不适当的影响。

答案 6 :(得分:1)

当然,显然你可以写:

class MyClass{
   ...
   public int hashCode(){
      return 1;
   }
   ...
}

在这种情况下,MyClass的所有实例都将具有相同的哈希码。

答案 7 :(得分:0)

是的,您当然可以拥有多个具有相同哈希码的对象。但是,通常这不会导致问题,因为使用对象哈希码的java.util。*数据结构将其用作存储返回相同哈希的所有对象的“存储桶”的键。

答案 8 :(得分:0)

Object a = new Integer(1);
Object b = new Integer(1);

System.out.printf(" Is the same object?     = %s\n",(a == b ));
System.out.printf(" Have the same hashCode? = %s\n",( a.hashCode() == b.hashCode() ));

打印:

Is the same object?     = false
Have the same hashCode? = true

答案 9 :(得分:-2)

在32位环境中,我怀疑任何JVM都会为不同的对象返回相同的“身份哈希码”。但在64位,这当然是一种可能性;鉴于我们现在的记忆力有限,碰撞的可能性仍然非常小。