ArrayList

        ArrayList就是数组列表,主要用来装载数据,当我们装载的是基本类型的数据int,long,boolean,short,byte…的时候我们只能存储他们对应的包装类,它的主要底层实现是数组Object[] elementData。与它类似的是LinkedList,和LinkedList相比,它的查找和访问元素的速度较快,但新增,删除的速度较慢。

小结:ArrayList底层是用数组实现的存储。

特点:查询效率高,增删效率低,线程不安全。使用频率很高。

1. 初始化

        ArrayList可以通过构造方法在初始化的时候指定底层数组的大小。通过无参构造方法的方式ArrayList()初始化,则赋值底层数 Object[] elementData 为一个默认空数组 Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {} 所以数组容量为0,只有真正对数据进行添加add时,才分配默认DEFAULT_CAPACITY = 10的初始容量。如果你传入了初始值大小,那就使用你传入的参数,如果没,那就使用默认的。下面为源码:

                             

 注意:ArrayList(int initialCapacity)并不会初始化数组的大小,这是属于 Java Bug中的一个经典问题。

                                  

2. ArrayList 的扩容机制

        ArrayList 的底层数据结构为数组,数组的长度是有限制的,而ArrayList是可以存放任意数量对象,长度不受限制,它是通过数组扩容的方式去实现的。它的扩容机制为:它会重新定义一个新数组,新数组的长度为原来数组长度的 1.5 倍,然后把原数组复制到新的数组中,再把原数组的地址换到新数组上。

3. ArrayList 的 add 操作

       在添加元素时,会先校验数组的长度,若长度不够则需要进行扩容。

                        

      在扩容的时候,老版本的jdk和8以后的版本是有区别的,8之后的效率更高了,采用了位运算,右移一位,其实就是除以2这个操作。

                        

      指定位置新增的时候,在校验之后的操作很简单,就是数组的copy,源码如下图:

                    

4.  ArrayList 的 remove 操作

      删除其实跟新增是一样的,不过叫是叫删除,但是在代码里面我们发现,他还是在copy一个数组。

                      

     打个比方,我们现在要删除下面这个数组中的index5这个位置,  那代码他就复制一个index5+1开始到最后的数组,然后把它放到index开始的位置,index5的位置就成功被”删除“了其实就是被覆盖了,给了你被删除的感觉。同理他的效率也低,因为数组如果很大的话,一样需要复制和移动的位置就大了。

                                                                  

                                            

5. 线程安全问题

        ArrayList 不是线程安全的,线程安全版本的数组容器是Vector。Vector的实现很简单,就是把所有的方法统统加上了synchronized 关键字。也可以不使用Vector,用 Collections.synchronizedList 把一个普通ArrayList包装成一个线程安全版本的数组容器也可以,原理同 Vector 是一样的,就是给所有的方法套上一层synchronized。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值