2020-10-15

[hashmap的底层实现TOC]
hashmap的底层是数组加单向链表存放数据的,它的默认长度是16,加载因子是0.75,扩容阈值是默认长度乘以加载因子;
比如我们通过无参构造方法实例化出hashmap时,会默认给hashmap加载因子设置成0.75,这时hashmap并没有开辟空间,只有在调用put方法放值是才开始开辟空间。
put方法开辟空间后
第一步,判断传入的键是否是null,如果是null,直接放入到node中,并返回。
第二步,如果存放的键不是null, 接着往下走,下面判断条件是当前要存放的值是否在hashmap中存在,如果存在直接执行覆盖操作。
第三步,如果要存放的值不存在,就循环单向链表,比对单向链表中的每个值是否和传入的值一致,如果一致,直接跳出循环,拿新的值翻盖掉老值。如果单向链表的值都没有和新传入的值一致,那就在单向链表的最后面插入新值,在插入新值后进行判断,判断单向链表的长度是否超过8个,如果超过8个,单向链表就会变成红黑树,这样的目的是为了提升查询效率。
第四步,判断size的长度是否大于阈值(阈值=数组长度*加载因子),如果大于阈值就进行扩容。
在put方法最后有一个++modCount的属性,这个属性在put、get、remove方法中都有使用,这个属性是集合的一个fail fast机制,是为了防止集合多线程情况下,一个线程正在操作迭代器的foreach查询时,如果有其它线程执行增删改的操作,就会造成了查询数据不一致,这时查询就会抛异常,以保证数据的安全性。
modCount类似于一个乐观锁的机制,它只能保证数据在一定情况下安全,但不能保证绝对安全,所以hashmap还是一个线程非安全的。

为什么要设置0.75的扩容因子?
设置0.75的扩容因子是解决“哈希冲突”和“空间利用率”矛盾的一个折衷方案。跟数据结构要么查询快要么插入快一个道理,hashmap就是一个插入慢、查询快的数据结构。
加载因子是表示Hash表中元素的填满的程度。加载因子越大,填满的元素越多,空间利用率越高,但hash冲突的几率就会加大,冲突的记录大会造成查找的成本高。
加载因子越小,填满的元素越少,冲突的机会减小,但空间浪费多了,但查找的成本小了很多。
所以,0.75是在 "冲突的几率"与"空间利用率"之间寻找一种平衡与折衷。

这是一个 SQL 语句,用于向借阅表中插入数据。该表包含以下字段:借阅编号、读者编号、书籍编号、借阅日期、归还日期、借阅状态。每条数据表示一次借阅记录。其中借阅编号、读者编号、书籍编号、借阅日期和借阅状态是必填项,归还日期为可选项,如果借阅状态为“已还”则必须填写归还日期。 具体插入的数据如下: - 借阅编号:100001,读者编号:123413,书籍编号:0001,借阅日期:2020-11-05,归还日期:NULL,借阅状态:借阅 - 借阅编号:100002,读者编号:223411,书籍编号:0002,借阅日期:2020-9-28,归还日期:2020-10-13,借阅状态:已还 - 借阅编号:100003,读者编号:321123,书籍编号:1001,借阅日期:2020-7-01,归还日期:NULL,借阅状态:过期 - 借阅编号:100004,读者编号:321124,书籍编号:2001,借阅日期:2020-10-09,归还日期:2020-10-14,借阅状态:已还 - 借阅编号:100005,读者编号:321124,书籍编号:0001,借阅日期:2020-10-15,归还日期:NULL,借阅状态:借阅 - 借阅编号:100006,读者编号:223411,书籍编号:2001,借阅日期:2020-10-16,归还日期:NULL,借阅状态:借阅 - 借阅编号:100007,读者编号:411111,书籍编号:1002,借阅日期:2020-9-01,归还日期:2020-9-24,借阅状态:已还 - 借阅编号:100008,读者编号:411111,书籍编号:0001,借阅日期:2020-9-25,归还日期:NULL,借阅状态:借阅 - 借阅编号:100009,读者编号:411111,书籍编号:1001,借阅日期:2020-10-08,归还日期:NULL,借阅状态:借阅
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值