java求职篇——基础集合

5 篇文章 0 订阅

1.ArrayList

扩容规则

  • ArrayList调用无参构造函数时,数组大小为0。

  • 当传入参数时,则创建指定大小空间的数组

  • 当传入集合时,则会根据集合大小创建初始容量

  • 当容量不足时,数组会进行扩容,长度为之前的1.5倍。

例如:[0,10,15,22,33,49...]

  • 当传入集合个数大于扩容规则时,会取较大值

例如:当我们调用无参构造函数时,初始大小为0,但我们传入一个14个元素的数组时,容量并不会先扩大到10再扩大到15,而是会直接扩大到14,取较大值。

fail-fast、fail-safe机制

  • fail-fast指的是当数组遍历的时候,其他人对数组进行修改,则会抛出异常

  • fail-safe指的是当数组遍历的时候,其他人来修改数组的时候,应该会有应对的策略,例如牺牲一致性继续遍历

Iterator_fail-fast、fail-safe原理分析

  • 当我们使用foreach首次输出元素时会new一个迭代器的对象,在list中存在一个modCount元素,会记录集合修改的次数。

  • 遍历数组时,会将集合的修改次数传给迭代器expectedModCount,迭代器遍历的时候会进行判断,集合修改次数与初始化时传的值是否相同,以次来判断遍历时有无修改了集合。

CopyOnWriteArrayList是fail-safe的典型代表,遍历的同时可以修改,原理是读写分离。

2.LinkedList

ArrayList与LinkedList

ArrayList

  1. 基于数组,需要连续存储

  2. 随机访问快(实现了RandomAccess接口)

  3. 尾部插入删除性能可以,其他部分插入删除需要移动数据性能低

  4. 可以利用cpu缓存,局部性原理

LinkedList

  1. 基于双向链表

  2. 随机访问慢

  3. 头部插入删除性能高

  4. 占用内存多

注:

RandomAccess接口为空接口,若实现该接口,则在遍历时会通过找下标的方式去遍历。若没实现只能通过迭代器去访问。

3.HashMap(重点)

  • 底层数据结构,1.7与1.8的区别

    • 1.7数组+链表,1.8数组+链表(元素少于等于八个时)、红黑树

HashMap存储原理

  • 计算元素的哈希码,经过二次hash对map长度进行求余,得到桶下标

  • 桶下标即为数组的下标,若存在多个元素通下表相同,则用链表链接

  • 当元素达到hashmap长度的3/4时会进行扩容

  • 当容量达到64且链表长度达到8个以上时会进行链表转换红黑树

为什么不一上来便树化?

  • 红黑树用来避免Dos攻击,防止链表长度过长降低性能

  • hash表的查找更新时间复杂度为O(1),红黑树的查找效率为O(log2n),而且TreeNode占用空间也比Node大

  • hash值足够随机时候,符合泊松分布,负载因子为0.75时,长度超过八的概率是0.00000006。

红黑树退化链表的两种情况

  • 扩容时进行差分树,链表的长度小于等于6

  • remove结点之前若root、root.left、root.left.left、root.right为null,则会退化成链表

索引的计算方法

  • 计算出对象的hashCode,在调用HashMap的hash()方法进行二次哈希,使用&(capacity-1)得到索引

  • 二次哈希的目的是为了让哈希分布更均匀

HashMap的容量为啥是2的n次幂

  • 计算索引时,如果是2的n次幂,可以使用位运算来代替模运算,效率更高。扩容时hash&odlCap==0的元素留在原来位置,否则新的位置=旧位置+oldCap

HashMap的put方法流程

  1. HashMap是惰性创建数组,首次使用put才会创建数组

  2. 计算索引

  3. 如果桶下标还未占用,则先创建Node占位,返回k-v

  4. 如果桶下标被占用了

    1. 如果是普通的链表,则走链表的添加逻辑,如果查过树化阈值则走树化逻辑

    2. 已经是TreeNode走红黑树的更新逻辑

  5. 返回前检查容量是否超过阈值,一旦超过则进行扩容

1.7和1.8put流程有何不同

  1. 链表插入节点时,1.7是头插法,1.8是尾插法

  2. 1.7是大于等于阈值且 没有空位时才扩容,1.8是大于阈值就扩容

  3. 1.8计算Node索引时,会优化

负载因子为何默认是0.75

  1. 在空间占用与查询时间之间取得较好的权衡

  2. 大于这个值,节省空间,但链表就会比较长影响性能

  3. 小于这个值,冲突减少,扩容更频繁,空间占用多

:多线程下

  1. 1.7会发生扩容死链问题

  2. 1.7、1.8会发生数据错乱问题

key值要求

  1. HashMap的key可以为null

  2. 作为key对象,必须实现hashCode和equals,并且key的内容不能修改(hashCode相同的两个对象不一定相同,但是equals相同的两个对象,hashCode一定相同)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狗头实习生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值