「这是我参与11月更文挑战的第7天,活动详情查看:2021最后一次更文挑战」
ArrayList
- ArrayList的底层是动态数组,特点是:查找快,增删慢,默认容量为10,每次容量满之后,采用1.5倍大小进行扩容
LinkedList
- 采用双向链表结构存储数据,适用于动态的插入和删除操作
- LinkedList,双向链表,优点,增加、删除元素,用时很短。但是因为没有索引,对索引的操作,比较麻烦,只能循环遍历,但是每次循环的时候,都会先判断一下,这个索引位于链表的前部分还是后部分,每次都会遍历链表的一半 ,而不是全部遍历。 双向链表,都有一个previous和next, 链表最开始的部分都有一个first指向第一个元素,和last 指向最后一个元素。增加和删除的时候,只需要更改一个previous和next,就可以实现增加和删除。
请你讲讲数组(Array)和列表(ArrayList)的区别?什么时候应该使用Array而不是ArrayList?
-
Array和ArrayList的不同点:
- Array可以包含基本类型和对象类型,ArrayList只能包含对象类型。
- Array大小是固定的,ArrayList的大小是动态变化的。
- ArrayList提供了更多的方法和特性,比如:addAll(),removeAll(),iterator()等等。
- 对于基本类型数据,集合使用自动装箱来减少编码工作量。但是,当处理固定大小的基本数据类型的时候,这种方式相对比较慢。
HashMap
-
底层实现是数组+链表+红黑树的形式,同时他的数组默认容量是16,扩容因子是0.75,每次扩容2倍。即每次容量达到75%时,数组容量进行2倍扩容。
-
当HashMap中的其中一个链表的对象个数如果达到了8个,此时如果数组长度没有达到64,那么HashMap会先扩容解决,如果已经达到了64,那么这个链表会变成红黑树,节点类型由Node变成TreeNode类型。当然,如果映射关系被移除后,下次执行resize方法时判断树的节点个数低于6,也会再把树转换为链表。
-
1.8之后为什么采用尾插法而不是头插法?
- 1.7是用单链表进行纵向延伸的,当采用头插法时会容易出现逆序且环形链表死循环的问题,而1.8之后的尾插法可以进行避免。
-
HashMap是先插入还是先扩容?
- HashMap初始化时首次插入数据时先进行扩容再插入,之后每当需要扩容时,则先插入再扩容
-
为什么负载因子是0.75不是0.5不是1?
- 负载因子是0.75时是效率比较高的,如果是0.5,临界值是8这样很容易就会触发扩容,而且此时还有一半的容量还没有使用,如果是1,则当数据占满时才扩容,会导致数据插入的时间增加。