详解java集合之ArrayList——底层实现是一个Object数组。分析ArrayList的自动扩容,原来不一定是1.5倍
ArrayList的底层实现——非private权限的Object数组
ArrayList的类结构图
1. ArrayList的创建
1.1 参数为空的构造方法——ArrayList内部的Object数组使用默认的空数组,被初始化为{}
1.2 初始容量作为参数的构造方法——会直接创建相应大小的Object数组
1.3 Collection对象作为参数的构造方法
2. ArrayList添加元素时的动态扩容机制
2.1 初始容量为0或者使用参数为空的构造方法创建的ArrayList对象自动扩容
2.1.1 源码分析:追踪add方法,最终追踪到grow方法。
2.1.2 初始容量为0或者使用参数为空的构造方法得到的内部Object数组(elementData属性)为{},也就是elemenntData.length=0,并且size=0。DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {},DEFAULT_CAPACITY = 10,源码如下。
2.1.3 grow方法分析
2.2 后期添加元素的自动扩容分析
2.2.1 需要注意的是,每次ArrayList数组满了(size == elementData.length)才会扩容。其次,因为每次扩容有两个值可取,如果是取原始容量的一半进行扩容,那么扩容倍数是1.5倍,不然ArrayList扩容倍数不一定。
3. ArrayList移除元素
3.1 不管是按索引移除还是直接移除对象,最终都是通过fastRemove方法按索引移除对象,源码追踪如下。
3.2 需要注意的是,直接移除对象时,查找对象使用的是equals方法。
3.3 fastRemove方法最终底层使用数组移动的arraycopy方式移除元素,源码如下。
4. ArrayList查找某个元素
4.1 indexOf方法查找元素并返回索引下标,内部通过遍历数组查找元素。所以常说数组查询快,链表查询慢,查询是指定位。如果是查找的话,数组和链表一样都得遍历。
5. ArrayList获取某个索引或更改某个索引的元素
5.1 获取某个索引元素,直接通过下标取出数组元素
5.2 更改某个索引的元素,直接通过下标更改数组元素
6. ArrayList的其它方法
6.1 ArrayList内没有toString方法,使用了间接父类AbstractCollection的toString方法,遍历每个元素并调用各自的toString方法,最终使用StringBuffer拼接。
6.2 ArrayList使用clear()方法清空数据,内部是将各个元素指向null。
6.3 ArrayList的size方法得到当前元素个数,而不是内部elementData数组长度。
6.4 ArrayList的toArray方法得到的数组是Object类型,需要自己强转。
总结
以上是生活随笔为你收集整理的详解java集合之ArrayList——底层实现是一个Object数组。分析ArrayList的自动扩容,原来不一定是1.5倍的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: Future和CompletableFu
- 下一篇: Integer及String的equal