Java 字符串与其他类对象的哈希代码

Java 字符串与其他类对象的哈希代码,java,hashcode,Java,Hashcode,问题/困惑: 对象类的默认哈希代码似乎考虑了对象引用,而不仅仅是内容,否则为什么同名的employee类对象会产生不同的哈希代码? 如果对象类的默认实现有一些仅基于内容的哈希算法,那么就不需要重写hashCode方法,只要我的equals范例符合按位兼容性 有什么办法消除这种混淆吗?默认的hashCode()既不基于引用,也不基于系统中的任何地址。它是存储在标题中的随机生成的数字。它这样做是为了在不改变hashCode()的情况下移动对象,并且hashCode是合理随机的 注: 在一次小GC之

问题/困惑:
对象类的默认哈希代码似乎考虑了对象引用,而不仅仅是内容,否则为什么同名的employee类对象会产生不同的哈希代码? 如果对象类的默认实现有一些仅基于内容的哈希算法,那么就不需要重写hashCode方法,只要我的equals范例符合按位兼容性

有什么办法消除这种混淆吗?

默认的hashCode()既不基于引用,也不基于系统中的任何地址。它是存储在标题中的随机生成的数字。它这样做是为了在不改变hashCode()的情况下移动对象,并且hashCode是合理随机的

注:

  • 在一次小GC之后,eden空间是空的,并且创建的第一个对象始终位于同一地址。它没有相同的哈希代码
  • 默认情况下,对象是在8字节边界上创建的,因此较低的三位可以是所有000位,这对哈希代码不有用。如果使用压缩的OOP,较低的位可能不会被存储,但仍然不是非常随机的
  • 使用
    Unsafe
    可以读取甚至覆盖存储的哈希代码。在OracleJVM/OpenJDK上,哈希代码存储在距离对象开头1字节的位置
  • 用于存储哈希代码的位也用于baised锁定。获得对象的内置哈希代码后,它将不会使用有偏锁定
  • 您可以使用
    system.identityHashCode(x)
    获取任何对象的系统哈希代码,这是
    IdentityMap
    使用的

默认哈希代码将仅在引用上生成。内容与此无关。但是,其他类,如
String
或原语包装器提供了它们自己的基于内容的实现。这不能开箱即用,因为在许多情况下,
equals()
hashCode()
(以
java.util.Date
为例,它使用
cdate
fastTime
来提供hashcode—使用所有字段的默认实现永远不会知道这一点)。“考虑对象引用,而不仅仅是内容”,而不是内容。
class Employee {
  String name;

  Employee(String name) {
    this.name = name;
  }
  // hashCode method is not overridden
}

public class HashCodeConfusion {
  public static void main(String[] args) {
    Employee emp = new Employee("ABC");
    Employee emp1 = new Employee("ABC");

    if (emp == emp1) {
      System.out.println("Employee Same reference");
    } else {
      System.out.println("Employee Different reference");
    }
    if (emp.hashCode() == emp1.hashCode()) {
      System.out.println("Employee Same hash code");
    } else {
      System.out.println("Employee Different hash code");
    }

    // -----------------------------------

    String str = new String("ABC");
    String str1 = new String("ABC");

    if (str == str1) {
      System.out.println("String Same reference");
    } else {
      System.out.println("String Different reference");
    }
    if (str.hashCode() == str1.hashCode()) {
      System.out.println("String Same hash code");
    } else {
      System.out.println("String Different hash code");
    }
  }
}