HashCode

作者: CelloRen | 来源:发表于2018-03-26 22:41 被阅读0次

    hashCode在Object类中实现,在此先不做引申,仅介绍一个对象的hashCode是怎么产生的:
    首先查看Java.lang.Object:

    // Object is the root of the class hierarchy.
    // All objects, including arrays, implement the methods of this class.
    public class Object {
         // Returns a hash code value for the object. This method is
         // supported for the benefit of hash tables such as those provided by
         // HashMap
          public native int hashCode();
    }
    

    在Object类里是没有直接实现hashCode()方法的,我们只知道这是一个native方法,即非java实现的。
    它的实现可以在OpenJDK里找到(openjdk/jdk/src/share/native/java/lang/Object.c):

    static JNINativeMethod methods[] = {
        {"hashCode",    "()I",                    (void *)&JVM_IHashCode},
        {"wait",        "(J)V",                   (void *)&JVM_MonitorWait},
        {"notify",      "()V",                    (void *)&JVM_MonitorNotify},
        {"notifyAll",   "()V",                    (void *)&JVM_MonitorNotifyAll},
        {"clone",       "()Ljava/lang/Object;",   (void *)&JVM_Clone},
    };
    

    可以知道又和JVM_IHashCode有关;
    再找到JVM_IHashCode的定义(openjdk\hotspot\src\share\vm\prims\jvm.cpp):

    // java.lang.Object ///////////////////////////////////////////////
    JVM_ENTRY(jint, JVM_IHashCode(JNIEnv* env, jobject handle))
      JVMWrapper("JVM_IHashCode");
      // as implemented in the classic virtual machine; return 0 if object is NULL
      return handle == NULL ? 0 : ObjectSynchronizer::FastHashCode (THREAD, JNIHandles::resolve_non_null(handle)) ;
    JVM_END
    

    可以知道又和FastHashCode方法有关(openjdk\hotspot\src\share\vm\runtime\synchronizer.cpp);


    如图所示

    其中,FastHashCode中又有:

      hash = get_next_hash(Self, obj);  // allocate a new hash code
    

    可知实现在get_next_hash()方法中,其核心的代码是:

    else {
         // Marsaglia's xor-shift scheme with thread-specific state
         // This is probably the best overall implementation -- we'll
         // likely make this the default in future releases.
         unsigned t = Self->_hashStateX ;
         t ^= (t << 11) ;
         Self->_hashStateX = Self->_hashStateY ;
         Self->_hashStateY = Self->_hashStateZ ;
         Self->_hashStateZ = Self->_hashStateW ;
         unsigned v = Self->_hashStateW ;
         v = (v ^ (v >> 19)) ^ (t ^ (t >> 8)) ;
         Self->_hashStateW = v ;
         value = v ;
      }
    

    其中在thread.cpp中有定义:

    // thread-specific hashCode stream generator state - Marsaglia shift-xor form
      _hashStateX = os::random() ;
      _hashStateY = 842502087 ;
      _hashStateZ = 0x8767 ;    // (int)(3579807591LL & 0xffff) ;
      _hashStateW = 273326509 ;
    

    于是我们可以知道JDK8的hashCode()的产生是基于一个随机数和三个确定数的,至于为什么get_next_hash()方法中的核心代码是这样,这要援引一篇论文:
    Xorshift RNGs


    部分截图

    再深入就要涉及数学的推导和矩阵的运算了,我也没有完全吃透,有兴趣的可以看看这篇论文。
    思考:
    1.为什么JDK8的hashCode不引入对象的地址参与运算呢?
    2.既然是基于hash,那么必然有几率产生碰撞,碰撞产生时如何处理?
    3.hashCode和equal方法的联系
    4.hashCode和hashMap的联系

    相关文章

      网友评论

          本文标题:HashCode

          本文链接:https://www.haomeiwen.com/subject/uqvrcftx.html