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

Java 在JVM堆中,可以有多个具有相同哈希代码的对象吗?,java,hash,jvm,Java,Hash,Jvm,根据标题,堆上可以有多个具有相同哈希代码的对象吗?可以,因为可以有任意多个具有相同哈希代码的对象。例如,以下代码(不带内部字符串)显示了这一事实: String foo = new String("dfa"); String bar = new String("dfa"); assert foo != bar; // yields false, two distinct objects (references) assert foo.hashCode() == bar.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
是的,因为您可以拥有任意多个具有相同哈希代码的对象。例如,以下代码(不带内部字符串)显示了这一事实:

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

是的,hashcode是一种标准算法,它试图避免重复的“冲突”,但不能保证这一点


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

是的,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!
    }
}
对于一个不那么轻率的回答,考虑一下:

hashCode的总合同为:

... 剪 如果根据equalsObject方法两个对象相等,那么对两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。 对

对于一个不那么轻率的回答,考虑一下:

hashCode的总合同为:

... 剪 如果根据equalsObject方法两个对象相等,那么对两个对象中的每个对象调用hashCode方法必须产生相同的整数结果。
在32位环境中,我怀疑任何JVM都不会为不同的对象返回相同的“标识哈希代码”。但在64位中,这当然是一种可能性;考虑到我们现在有限的内存,冲突的可能性仍然很小。

在32位环境中,我怀疑任何JVM都不会为不同的对象返回相同的“标识哈希代码”。但在64位中,这当然是一种可能性;考虑到我们现在有限的内存,冲突的可能性仍然很小。

关于散列码:是的,它们几乎是唯一的,但不是唯一的:这取决于实现/理论它们的独特性

但是如果我们谈论JVM,我们必须首先谈论您所指的哈希代码类型

如果您谈论HashMap在f.e.中使用的hashCode方法的结果,那么答案是:它取决于您的实现和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();
    }
}
在本例中,您将得到不同的哈希值,在大多数情况下,它们是不同的,但不一定是唯一的


致以最良好的祝愿

关于散列码:是的,它们几乎是唯一的,但不是唯一的:这取决于实现/理论它们的独特性

但是如果我们谈论JVM,我们必须首先谈论您所指的哈希代码类型

如果您谈论HashMap在f.e.中使用的hashCode方法的结果,那么答案是:它取决于您的实现和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();
    }
}
在本例中,您将得到不同的哈希值,在大多数情况下,它们是不同的,但不一定是唯一的

致以最良好的祝愿

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

分配2^32+1个对象。可能需要一个64位的虚拟机和大量的内存

现在,您的hashCode方法无论多么聪明,都必须有冲突。

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

分配2^32+1个对象。可能需要一个64位的虚拟机和大量的内存


现在,您的hashCode方法无论多么聪明,都必须有冲突。

是的,您当然可以有多个对象使用相同的hashCode。但是,这通常不会引起问题,因为使用对象哈希代码的java.util.*数据结构将其用作存储返回相同哈希的所有对象的bucket中的键。

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

您可以,但这通常不是一个好主意。上述示例多次提到:

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实现的想法是尽量减少冲突,以使性能不会受到不适当的影响。

您可以,但这通常不是一个好主意。上述示例多次提到:

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实现的思想是避免冲突,从而使性能不会受到不适当的影响。

当然,显然,您可以编写:

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

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

当然,显然您可以编写:

class MyClass{
   ...
   public int hashCode(){
      return 1;
   }
   ...
}
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() ));
在这种情况下,MyClass的所有实例都将具有相同的哈希代码

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
印刷品:

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


更详细的回答:Java规范没有根据对象的哈希设置任何特定的期望值。一个常量函数将是一个兼容的实现…是的,我会很感激证明。谢谢。更详细的回答:Java规范没有根据对象的散列设置任何特定的期望值。一个常量函数将是一个兼容的实现…是的,我会很感激证明。谢谢。@Peter:奇怪。我从来没有见过。@Peter:那绝对是件可怕的事。@sylvarking:埃里克森怎么了?@sylvarking我见过!调试花费了一段时间,因为我们正在使用哈希存储到缓存中,并且对象正在被覆盖。@robin:当可能存在重复项时,为什么要使用哈希作为键??当无法复制时,这不会导致overwriting@Peter:奇怪。我从来没有见过。@Peter:那绝对是件可怕的事。@sylvarking:埃里克森怎么了?@sylvarking我见过!调试花费了一段时间,因为我们正在使用哈希存储到缓存中,并且对象正在被覆盖。@robin:当可能存在重复项时,为什么要使用哈希作为键??当无法复制时,这不会导致覆盖N.B。Object.hashCode的措辞是,不同的对象将尽可能具有不同的哈希代码。这类代码意味着在32位系统上使用不同的散列码,这是完全实用的。然而,大多数类都会有许多可能的冲突,因为散列码只是一个int…N.B。Object.hashCode的措辞是,不同的对象将尽可能具有不同的哈希代码。这类代码意味着在32位系统上使用不同的哈希代码,这是完全实用的。然而,大多数类都会有许多可能的冲突,因为哈希代码只是一个int…只需在浮点上迭代,就有了充分的浮点上迭代,就有了充分的数据