• 【JVM】-NO.112.JVM.2 -【JDK11 HashMap详解-2-tab[i = (n


    Style:Mac

    Series:Java

    Since:2018-09-10

    End:2018-09-10

    Total Hours:1

    Degree Of Diffculty:5

    Degree Of Mastery:5

    Practical Level:5

    Desired Goal:5

    Archieve Goal:3

    Gerneral Evaluation:3

    Writer:kingdelee

    Related Links:

    http://www.cnblogs.com/kingdelee/

    http://www.runoob.com/java/java-operators.html

    1.key是如何hash后去找到合适的坑填进去?

    Node<K,V>[] tab; Node<K,V> p; int n, i;
    logger.info("将table赋给tab");
    if ((tab = table) == null || (n = tab.length) == 0) {
        logger.info("table为null");
        n = (tab = resize()).length;    // 1.当未指定初始容量时,进行resize, 得到容量值赋给n=16; 获得新的节点给tab;已经存在节点时不再进来
        logger.info("tab renTab");
    }
    logger.info("tab[i = (n - 1) & hash]):  tab["+((n - 1) & hash)+"] i:" + ((n - 1) & hash) + ", hash:" + hash);
    if ((p = tab[i = (n - 1) & hash]) == null)  // i: (16-1) & 10 = 10,未存在节点的情况下,让新节点P指向数组节点tab中的hash后的节点,创建节点数组;已经存在节点时不再进来
    {
        logger.info("创建一个新节点,tab["+i+"]指向这个节点" + "hash:" + hash + ",value:" + value);
        tab[i] = newNode(hash, key, value, null);   // 仅在p节点为空的情况下,创建刚刚新节点指向hash后为空的节点的位置
    }
    

      

    重点看:

    n = tab.length
    或者
    n = (tab = resize()).length; 
    
    填坑入槽:
    tab[i = (n - 1) & hash]
    

    初始化时,n为16.

    推论:

    1.ab进行&运算,c一定<=ab中的最小值;即 (n-1) & hash的值i,一定是在长度内的,不会越界,且坑位受hash的散列能力影响

    疑问:如果len长度不是16而是17或者18呢?

    即len是17时,n-1则为16,即a为16;len是18时,n-1则为17,即a为17

    发现c有很多是一样的,即很多值都掉到同一个坑位里了。散列能力极差。

    观察发现,有且只有a为1111,11111,111111....都是1时,b的递增,c才会依次递增

    即a为是2的n次幂-1

    结论:

    1.len一定是2的次幂,才能保证横向散列的能力,让key能够松散的填入tab数组坑中。

      

  • 相关阅读:
    Redis 安全
    Redis 数据备份与恢复
    Redis 服务器
    Redis 连接
    Redis 脚本
    Linux中使用netstat命令的基本操作,排查端口号的占用情况
    ElasticSearch 常用查询语句
    GO代码风格指南 Uber Go (转载)
    coding 注意事项(总结中)
    Byte字节
  • 原文地址:https://www.cnblogs.com/kingdelee/p/9724725.html
Copyright © 2020-2023  润新知