散列概念的新手,我读过 HashMap、HashTable 等使用散列,我们需要指定一个键,同时用它存储一个值
但是,由于每个对象都有一个 hashCode() 方法,java 是否在内部通过特定字段对对象使用 hashCode 来管理它(列表除外)
Object.hashCode() 的javadoc回答了这个问题:
在合理可行的情况下,由 Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。(这通常通过将对象的内部地址转换为整数来实现,但 JavaTM 编程语言不需要这种实现技术。)
(强调我的)
所以不,没有额外的字段来存储 hashCode(除非某些类决定覆盖它并使用专用字段来实现它)。
并且 hashCode 不被 JVM 使用,而是被基于散列的集合(Hashtable、HashMap、HashSet,...)
不,hashCode() 方法用于定义一个键,用于将其与对象的实例相关联。
它用于标识对象的特定实例,并不意味着使用散列技术来管理 Java 对象。
您可以覆盖 hashCode() 方法来定义您自己的分配键的方式来标识对象的实例。
如果您问“Java 是否用于hashCode()
对对象进行幕后管理?”,我想答案是“否”。考虑一下如果你写了一个非常糟糕的覆盖会发生什么hashCode()
; 您会期望 JVM 内部结构会因此受到阻碍吗?
public native int hashCode();
hashCode
是本机实现。但没有字段与之关联。
This is typically implemented by converting the internal address of the
object into an integer, but this implementation technique is not required
by the JavaTM programming language.
在 OpenJDK/Oracle JVM 中,计算初始哈希码的常用方法是基于第一次请求时的内存地址。对象在内存中移动,所以每次都使用地址不是一个好的选择。哈希码不是实际地址——它通常是八的倍数,不适合直接在哈希表中使用,尤其是具有两倍大小的幂。注意身份哈希码不是唯一的。
根据文档
jvmtiError GetObjectHashCode(jvmtiEnv* env, jobject object, jint* hash_code_ptr)
和
For the object indicated by object, return via hash_code_ptr a hash code.
This hash code could be used to maintain a hash table of object references,
however, on some implementations this can cause significant performance
impacts--in most cases tags will be a more efficient means of associating
information with objects. This function guarantees the same hash code value
for a particular object throughout its life.