大家好,又见面了,我是你们的朋友全栈君。
1. ArrayList() 会使用长度为零的数组
如果是无参构造,则会将DEFAULTCAPACITY_EMPTY_ELEMENTDATA
(空对象)的值复制给elementData
, 再执行添加操作时,才会给数组赋值(见第四点)
DEFAULTCAPACITY_EMPTY_ELEMENTDATA
空对象
追踪add方法可到这儿
//1 . add(E e)
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
//2.ensureCapacityInternal
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//3.calculateCapacity
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
2. ArrayList(int initialCapacity) 会使用指定容量的数组
3. public ArrayList(Collection<? extends E> c) 会使用 c 的大小作为数组容量
4. add(Object o) 首次扩容为 10,再次扩容为上次容量的 1.5 倍
// private static final int DEFAULT_CAPACITY = 10;
// 如果是扩容,则扩容老数据组的1.5倍
5. addAll(Collection c) 没有元素时,扩容为 Math.max(10, 实际元素个数),有元素时为 Math.max(原容量 1.5 倍, 实际元素个数)
后面主要还是扩容这一段代码:
注: 有元素时为什么为 是Math.max(原容量 1.5 倍, 实际元素个数),主要是这里可能发生一次扩容,如果
原数组长度
+新添加的c的长度
大于原容量,则会扩容一次成为原容量的1.5倍;如果原数组长度
+新添加的c的长度
不超过原容量,则不会扩容
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
```
测试代码:
···java
public class ArrayListAddCapacity {
public static void main(String[] args) {
// System.out.println(arrayListGrowRule(30));
// testAddAllGrowEmpty();
testAddAllGrowNotEmpty();
}
/** * 空构造方法 * @param n * @return */
private static List<Integer> arrayListGrowRule(int n) {
List<Integer> list = new ArrayList<>();
int init = 0;
list.add(init);
if (n >= 1) {
init = 10;
list.add(init);
}
for (int i = 1; i < n; i++) {
init += (init) >> 1;
list.add(init);
}
return list;
}
/** * addAll(Collection c) 没有元素时 */
private static void testAddAllGrowEmpty() {
ArrayList<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(1, 2, 3));
list.addAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
System.out.println(length(list));
}
/** * addAll(Collection c) 有元素时 */
private static void testAddAllGrowNotEmpty() {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 1; i++) {
list.add(i);
}
list.addAll(Arrays.asList(1, 2, 3));
System.out.println(length(list));
list.addAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
System.out.println(length(list));
}
/** 反射获取数组长度 */
public static int length(ArrayList<Integer> list) {
try {
Field field = ArrayList.class.getDeclaredField("elementData");
field.setAccessible(true);
return ((Object[]) field.get(list)).length;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
来源: https://www.bilibili.com/video/BV15b4y117RJ?p=32
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/136818.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...