Java 字符串与其他类对象的哈希代码
问题/困惑:Java 字符串与其他类对象的哈希代码,java,hashcode,Java,Hashcode,问题/困惑: 对象类的默认哈希代码似乎考虑了对象引用,而不仅仅是内容,否则为什么同名的employee类对象会产生不同的哈希代码? 如果对象类的默认实现有一些仅基于内容的哈希算法,那么就不需要重写hashCode方法,只要我的equals范例符合按位兼容性 有什么办法消除这种混淆吗?默认的hashCode()既不基于引用,也不基于系统中的任何地址。它是存储在标题中的随机生成的数字。它这样做是为了在不改变hashCode()的情况下移动对象,并且hashCode是合理随机的 注: 在一次小GC之
对象类的默认哈希代码似乎考虑了对象引用,而不仅仅是内容,否则为什么同名的employee类对象会产生不同的哈希代码? 如果对象类的默认实现有一些仅基于内容的哈希算法,那么就不需要重写hashCode方法,只要我的equals范例符合按位兼容性 有什么办法消除这种混淆吗?默认的hashCode()既不基于引用,也不基于系统中的任何地址。它是存储在标题中的随机生成的数字。它这样做是为了在不改变hashCode()的情况下移动对象,并且hashCode是合理随机的 注:
- 在一次小GC之后,eden空间是空的,并且创建的第一个对象始终位于同一地址。它没有相同的哈希代码
- 默认情况下,对象是在8字节边界上创建的,因此较低的三位可以是所有000位,这对哈希代码不有用。如果使用压缩的OOP,较低的位可能不会被存储,但仍然不是非常随机的
- 使用
可以读取甚至覆盖存储的哈希代码。在OracleJVM/OpenJDK上,哈希代码存储在距离对象开头1字节的位置Unsafe
- 用于存储哈希代码的位也用于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");
}
}
}