**扩容规则**
1. ArrayList() 会使用长度为零的数组
2. ArrayList(int initialCapacity) 会使用指定容量的数组
3. public ArrayList(Collection<? extends E> c) 会使用 c 的大小作为数组容量
4. add(Object o) 首次扩容为 10,再次扩容为上次容量的 1.5 倍
数组前20次扩容的容量
public static void main(String[] args) {
System.out.println(arrayListGrowRule(20));
}
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;
}
控制台输出:
[0, 10, 15, 22, 33, 49, 73, 109, 163, 244, 366, 549, 823, 1234, 1851, 2776, 4164, 6246, 9369, 14053, 21079]
增加0.5并不使用除法,而是使用位移的方式 15>>>1 等于 7 ,7+15 = 22
面试题:当需要向数组中添加100个元素,那么数组需要扩容多少次?
7次
5. addAll(Collection c) 没有元素时,扩容为 Math.max(10, 实际元素个数),有元素时为 Math.max(原容量 1.5 倍, 实际元素个数)
新数组的原始长度为0
public static void main(String[] args) {
testAddAllGrowEmpty();
}
private static void testAddAllGrowEmpty() {
ArrayList<Integer> list = new ArrayList<>();
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;
}
}
控制台输出:
数组长度:0
向空数组中addAll一个长度为3的数组,数组长度为10
public static void main(String[] args) {
testAddAllGrowEmpty();
}
private static void testAddAllGrowEmpty() {
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list.addAll(list2);
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;
}
}
控制台输出:
数组长度:10
向空数组中addAll一个长度为11的数组,下次扩容的长度大小与加入的数组长度作比较,取数量多的,为更高的效率,一次扩容可以解决的,不进行二次扩容
public static void main(String[] args) {
testAddAllGrowEmpty();
}
private static void testAddAllGrowEmpty() {
ArrayList<Integer> list = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
list2.add(5);
list2.add(6);
list2.add(7);
list2.add(8);
list2.add(9);
list2.add(10);
list2.add(11);
list.addAll(list2);
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;
}
}
控制台输出:
数组长度:11
public static void main(String[] args) {
testAddAllGrowNotEmpty();
}
private static void testAddAllGrowNotEmpty() {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list.addAll(list2);
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;
}
}
控制台输出:
数组长度:15
public static void main(String[] args) {
testAddAllGrowNotEmpty();
}
private static void testAddAllGrowNotEmpty() {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
ArrayList<Integer> list2 = new ArrayList<>();
list2.add(1);
list2.add(2);
list2.add(3);
list2.add(4);
list2.add(5);
list2.add(6);
list.addAll(list2);
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;
}
}
控制台输出:
数组长度:16