• 使用哈希值和&和2^n数组生成索引值的原理


    用&代替%的原因是&计算速度快

    先看这一段代码

    public int hash(Object key){
         return hash_code(key)&(table.length-1);//table.lenth的长度需要是2^n          
    }

    首先这个hash_code的方法是根据一个key值获取到一个哈希值,之后与后面的数进行与运算,对于不同的hash值,映射到对应的索引上

    (table是一个数组,它的索引值也为table.length-1)

    1.首先解释为什么table.length需要是2^n

    因为2^n的数的二进制表示有一个特点,那就是1开头,后面全是0,比如8是1000,16是10000,以此类推
    那么2^n-1的数的二进制表示有什么特点的,那就是0开头,后面全是1,比如7是0111,15是01111

    2.根据这个特点我们回到方法体本身,进行一个例子的计算

    假设有一个长度为16的数组,那么我怎么通过hash算法把不同的key值算出来的hash值映射到索引上去呢。
    假设其中某个key值的hash值的二进制表示为1101010011010,共13位
    16-1的二进制为01111
    进行&运算,位数上都为1才取1,其余取0
    1101010011010
    0000000001111
    ------------------
    0000000001010
    可以发现在01111之前的位数进行&运算出来都是0,那么有个问题,该计算结果1010的十进制值是10,那么请问&运算后最终的结果存不存在一个取值范围
    答案是存在,如果最终的计算结果为01111,那么就是&运算的最大值为15,如果最终的结果为00000,那么就是&运算的最小值为0
    这样一来,该&运算的取值范围只由后面这个2^n-1决定,又因为2^n-1又是该数组的索引的最大值,该数组索引的最小值也是0
    所以,任何哈希值进行&运算后都会映射到这个数组对应的索引上

    3.这就是根据hash值来定位索引的方式,当然会产生hash冲突,就是有多个哈希值经过&运算后的结果是一样的,这个就要通过链表来解决了,这个先按下不表

  • 相关阅读:
    Linux I2C核心、总线和设备驱动
    移植 Linux 内核
    同步、互斥、阻塞
    异步通知
    poll机制
    Linux异常处理体系结构
    字符设备的驱动
    进程间的通信—套接字(socket)
    进程间的通信—信号量
    Spring事件的应用
  • 原文地址:https://www.cnblogs.com/skyvalley/p/13966474.html
Copyright © 2020-2023  润新知