ArrayList学习笔记

1.ArrayList
ArrayList底层是数组实现的存储,与它类似的是LinkedList,两者间的区别:

  • ArrayList:查找与访问元素的速度快,但是新增、删除的速度慢。
  • LinkedList:新增、删除的速度快,查找的速度慢。

2.ArrayList为什么是线程不安全的还使用?

  • 平时的场景中,基本都是用来查询的,不会设计太频繁的新增和删除
  • 如果设计到新增和删除可以使用LinkedList。
  • 如果需要线程安全,可以使用Vector。

3.ArrayList底层是如何实现的?

  • 在new ArrayList()创建一个集合的时候,会初始化一个容量为0的Object[]
  • 当再次执行add添加数据的时候,才会默认分配一个capacity=10的初始容量

4.ArrayList可以存放无限长度的数组是如何实现的?
通过数组扩容方式,如果有一个长度为10的数组,要新增一个元素,发现数组已经满了,它会执行一下几个步骤:

  1. 重新定义一个长度为10+10/2的数组。
  2. 然后把原有的数组原封不动的复制到新得数组中,再把指向原数组中的地址换到新数组的地址。

5.ArrayList新增时为什么慢?

  1. 首先在新增的时候会进行一个长度校验的判断 ensureCapacityInternal,判断是否需要扩容。
  2. 扩容的时候,jdk8以后采用了位运算符,效率更高。

int newCapacity = oldCapacity + (oldCapacity>>2)

  1. 如果是新增指定位置的时候,校验后,就直接copy指定位置的元素到最后的元素,把新增的元素插入指定位置的数组后,再把之前copy的数组依次添加到后面。

若当数组较大的时候,新增一个指定位置的数组,后面的元素全部都要复制一边。然后涉及到扩容啥的速度自然而然就变慢了

6.ArrayList创建时指定数组大小是否会初始化数组长度?
不会,数组创建的时候是再add添加元素的时候。

7.ArrayList插入删除一定很慢么?
取决于你删除的元素离数组末端的元素有多远。

8.ArrayList删除是怎么实现的?
比如有一个数组长度为10。要删除index为2的元素。

  1. 先复制一个从 index+1 开始到最后的数组;即 3->10。
  2. 把这个新数组从原数组index的位置开始放到最后。

其实就是把原来的index下标的元素给覆盖掉了,给你一种被删除的感觉。
同理它的效率很低,如果数组很大,它需要复制和移动的位置就很大。

9.ArrayList线程安全么?
不安全,安全的数组容器时Vector。Vector的实现很简单:所有的方法加上了synchronized锁。

10.ArrayList适合做队列么?
不适合,队列一般时先进先出,如果使用ArrayList做队列,就需要再数组尾添加数据,数组头删除数据。无论如何总会有操作设计到数组的数据搬迁,即复制和移动。效率低下所以不适合做队列。

11.数组适合做队列么?
适合,ArrayBlockingQueue内部就是一个环形队列,它是一个定长队列。内部是用一个定长数组来实现的

环形队列:使用两个偏移量来标记数组的读位置和写位置,如果超过长度则折回到数组开头。

12.ArrayList与LinkedList遍历性能比较?
ArrayList比LinkedList快。

  • ArrayList的遍历最大的优势在于内存的连续性,cpu内部缓存结构会缓存连续内存片段,大幅度降低了读取内存的性能开销。
  • LinkedList是双向链表结构,内存是不连续的,并且如果get每一个元素都会导致之前遍历的元素重新遍历一边
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值