集合-ArrayList学习
1、特点:
- ArrayList 实现是一个动态数组,初始时是一个空数组。
- ArrayList 默认初始长度为0,在插入第一个元素的时候扩容为10,然后当数组存满的时候,数组会再次扩容,此时就扩容到原来的1.5倍。
- ArrayList 是线程不安全的。
2、分析:
2.1、创建一个ArrayList
ArrayList<String> list = new ArrayList<>();
按住Ctrl点击ArrayList<>()
进去我们可以看到,这是啥意思呢?
首先要明白this
是啥意思,其实此时this
就代表的是 ArrayList
。你在main中创建的ArrayList
其实就是一个空数组。
elementData
是声明了一个object类型的数组
DEFAULTCAPACITY_EMPTY_ELEMENTDATA
也是一个object类型的数组,这个数组是空的。
也就是说此时的数组长度是0
2.2、添加一个元素
list.add("12346");
按住Ctrl点击add
,然后看到ArrayList
中的add
方法。在调用add
方法时,它首先调用了ensureCapacityInternal
方法 ,然后把元素放进elementData
数组中,然后size++
之后返回一个布尔值。
ensureCapacityInternal
方法是干嘛呢?
它首先调用了calculateCapacity
传递了数组和数组的长度,然后调用了ensureExplicitCapacity
calculateCapacity
方法是干嘛呢?
它首选判断当前的数组是不是空数组,也就是是不是第一次插入元素。如果是就比较DEFAULT_CAPACITY
和minCapacity
谁大就返回谁,DEFAULT_CAPACITY = 10
而 minCapacity = 1
显然DEFAULT_CAPACITY
大也就把数组初始为10了。
如果不是空数组就直接返回当前数组的长度
ensureExplicitCapacity
方法是干嘛的呢?
它就是判断当前数组的元素个数是否大于数组的长度,如果大于就调用grow
grow
方法的作用
首先把数组的长度,赋值给oldCapacity
然后定义一个新的长度,让这个长度等于 旧的长度的1.5倍 ,之后判断此时的长度是否小于最小长度,如果小于就让把它的值重新赋值为最小长度。不然就判断此时的长度是否大于最大长度。如果大于就调用hugeCapacity
方法,并把返回的值赋给新的数组长度,然后把旧的数组元素,按照新的长度,复制给新的数组。 此时就完成了扩容
hugeCapacity
方法的作用
如果这个最小值小于0 就抛出错误,否则就判断它是否大于ArrayList
定义的默认最大长度,如果大于就返回 int类型的最大长度,否则就返回 arrayList
定义的默认最大长度 给到newCapacity