HashMap源码解析笔记

1 默认加载因子0.75f

2 hash数组默认是16

4 初始化时,如果传入了hash槽的容量大小,不是2的整数次幂,获取刚大于容量的整数次幂

5 key和value都允许null 如果key为null 则数据放在table[0]

6 关于hash因子,如果太大,空间能够充分利用,但是查询慢

如果太小,没存入多少数据就需要开始扩容,但是查询速度快

主要是链表的长度决定的,链表越长,查询速度就慢

8 table[i] 就可以得到改槽下面的链表的头节点

hashMap是单向链表

7  确认数据放在那个槽的算法

static int hash(int h) {
        // This function ensures that hashCodes that differ only by
        // constant multiples at each bit position have a bounded
        // number of collisions (approximately 8 at default load factor).
        h ^= (h >>> 20) ^ (h >>> 12);
        return h ^ (h >>> 7) ^ (h >>> 4);
    }


 static int indexFor(int h, int length) {
        return h & (length-1);
    }

首先根据Key.hashCode()  得到哈希值,如果调用hash方法得到一个值,最后indexfor返回的值就是hash数组的index

h&(length-1)相当于对length去模,只有在hash数组的大小为2的整数次幂才是如此,比%效率更高,hashtable还是用的%

与运算符   两个都为1才是1   否则是0 

|这个运算符是只要有一个是1   就得到1

^ 异或运算符,相同为1,不同为0

~ 取反运算符,对一个数据而言的

所以如果length是2的整数次幂,是偶数,则-1是奇数,奇数的最后一位是1,与运算符的最后一位可能是0,也可能是1,保证数据均匀的分布在hash数组里面

如果length是奇数,则与运算符的最后一位肯定是0,得到的一定是偶数,则hash数组中只有index为偶数的数组里卖弄才能放入数据


8 put和get方法

get相对比较简单,null的话从table[0]中查找,不为null则先获取槽,再遍历

put方法  首先要判断该key是否存在,如果存在,直接替换该key对应的value

如果不存在addentry  获取槽,放在链表的头部,同时要判断size++跟threshold的大小,如果大于总容量的3/4 则进行扩容。扩容所有的数据需要重新放置,很费时间

 threshold = (int)(capacity * loadFactor);  槽的数量*因子






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值