Java学习记——集合( Iterator)

开始分享之前,博客主要是为了记录学习。在学习过程中不免会出现错误,也欢迎大家在评论区指正。我会认真回复大家的。谢谢!!

内容介绍和学习途径

集合的初步学习,及相关总结。主要知识来源面试八股文鱼总的面试鸭小程序
吐槽一下,本来开开心心的刷着试题,结果需要99的会员。直接安排上。

学习总结

因为这是为了更加系统性的了解相关知识,我就直接做成树状图了
在这里插入图片描述
八股文面试题:
十二、简单说说算法时间复杂度和空间复杂度?时间复杂度有哪些排序情况如何?

时间复杂度:执行时间与数据增长关系

空间复杂度:储存空间与数据增长关系

常见的时间复杂度:O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n3)<O(nk)<O(2n)<O(n!)

十三、有了解ArrayList的底层实现原理不?

1.底层采用动态数组实现。

2.初始容量为0,当添加第一条数据才会初始化容量为10.

3.会扩容到原来容量的1.5倍,并且进行数据拷贝。

当添加到一定的时候,需要扩容。扩容情况如下:当前数组已使用长度(size)+1 < 当前整个数组长度大小 ? 继续存储 : 调用grow方法扩容(1.5倍)

新数据储存在size位置上,返回true。

十四、如何实现数组与List之间的互换?如果转换之后修改了原内容,转化后的会受影响吗?

Array使用了asList方法变成List,如果修改了数组内容,List会受影响。因为底层使用的Array类中的一个内部类ArrayList来构造的集合,集合的构造器中把我们传入的这个集合进行了包装而已,最终指向的都是同一个内存地址。

list使用了toArray方法变成Array,如果修改了list内容,数组是不会受影响。当调用了toArray以后,底层是它的是进行了数组的拷贝,跟原来的元素就没啥关系了。所以即使list进行了修改,数组也没有啥影响。

十五、ArrayList和LinkList的区别在那里?

1.底层的数据结构不同:ArrayList是动态数组,而LinkList底层是双向链表

2.效率上的不同:ArrayList是根据索引来查询,时间复杂度为O(1),如果在索引不明确的情况下需要遍历,故时间复杂度为O(n),在增删改操作上,在尾部的话,为O(1),其他部位,因为涉及到数组的移动,所以为O(n);LinkList必须遍历才能查询,故为O(n),如果在头和尾的位置上进行增删,时间复杂度为O(1),在未确定的情况下就需要遍历一遍即可,所以为O(n)。

3.空间上的区别:其实就是底层结构的不同,数组是连续储存的,空间利用率高;链表不仅要保存数据还有保存指向下一个节点的指针,空间也是不连续的,空间花费大。

4.线程安全:List线程是不安全的。

如何保证这两者线程安全:

A.在方法内使用,局部变量则是线程安全的。

B.使用线程安全的,如Collection.synchronizedList(new 对象)

十六、HashMap的实现原理

1,底层采用了hash表的数据结构,即数组和链表或者红黑树。

2.当我们往HashMap中put元素时,利用key的hashCode重新计算当前对象的元素在数组的下标

3.存储时,如果出现hash值相同的key,会出现两种情况,一是key相同,则会覆盖原始值。二是key不同(hash冲突),则将当前的key-value放入链表或者红黑树中。

4.获取时,直接找到hash值对应的下标,在进一步判断key是否相同,从而找到对应的值。

十七、HashMap在JDK1.7和JDK1.8的区别在哪里?

1.底层不一样数据结构不一样。之前是数组+链表,同时采用头插法进行存储Hash冲突;之后因为避免拉链法造成的链表过长和扩容的数据迁移的时候死循环,推出了新的数据结构为数组+(链表/红黑树),并且改成了尾插法。

2.链表的长度大于8且数组长度大于64,链表会转换成红黑树;当链表的元素删除时,如果小于等于6的话红黑树会退化成链表。

十八、HashMap的put方法的具体流程?

1.判断键值对数组table是否为null,否则执行resize()进行扩容(初始化)。

2.根据key计算索引下标i,判断table[i] ==null,条件成立,直接新建节点添加;不成立,情况如下:

A.判断table[i]的首个元素是否和key一样,如果相同直接覆盖value

B.判断table[i]是否为TreeNode,是则在TreeNode中插入键值对

C.遍历table[i],链表的尾部插入数据,然后判断链表长度是否大于8,大于8的话把链表转换为红黑树,在红黑树中执行插入操作,遍历过程中若发现存在直接覆盖value。

3.插入成功后,判断实际存在的键值对数量size是否超过了最大容量threshold(数组长度的0.75),如果超过,则进行扩容。

十九、讲一讲HashMap的扩容机制?

1,在添加元素或者初始化的时候需要调用resize()进行扩容,第一次添加数据初始化数组长度为16,以后每次扩容都是达到了扩容阀值(即数组长度的0.75)

2.每次扩容后的容量为原来的2倍。需要把老数组移动在新数组中。情况有如下几种?

A.没有Hash冲突的结点,则直接使用(e.hash & (newCap - 1))计算新数组的索引位置。

B.如果是红黑树的结点,直接添加在红黑树上。

C.如果是链表,则需要遍历链表,可能需要拆分链表,判断(e.hash & (newCap - 1))是否为0,该元素的位置要么停留在原始位置,要么移动到原始位置+增加的数组大小这个位置上。

二十、HashMap的寻址算法?为何HashMap的数组长度一定是2的次幂?

1,寻址算法:hash((h=key.hashcode())^(h>>>16)) &(n-1)

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

心得体会

今天感觉下来还是得多看多记,多想多练。对自己的Java知识又较大提升。今天的感悟就大致是这些。期待下一次的博客。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值