文章目录
引言
扩容规则
1. ArrayList() 无参构造扩容
2. ArrayList(int initialCapacity)扩容
3. public ArrayList(Collection<? extends E> c) 扩容
4. add(Object o)扩容
5. addAll(Collection c) 扩容
其他
引言
要注意的是,以下所有代码中用反射方式来更直观地反映 ArrayList 的扩容特征,但从 JDK 9 由于模块化的影响,对反射做了较多限制,需要在运行测试代码时添加 VM 参数 --add-opensjava.base/java.util=ALL-UNNAMED 方能运行通过
扩容规则
1. ArrayList() 无参构造扩容
ArrayList() 无参构造会使用长度为零的数组
ArrayList()源码
/** * Constructs an empty list with an initial capacity of ten. */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }
2. ArrayList(int initialCapacity)扩容
ArrayList(int initialCapacity) 使用指定容量的数组初始化ArrayList()
ArrayList(int initialCapacity)源码
/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }
3. public ArrayList(Collection<? extends E> c) 扩容
public ArrayList(Collection<? extends E> c) 会使用 c 集合 的大小作为数组容量
ArrayList(Collection<? extends E> c) 源码
/** * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collection's * iterator. * * @param c the collection whose elements are to be placed into this list * @throws NullPointerException if the specified collection is null */ public ArrayList(Collection<? extends E> c) { Object[] a = c.toArray(); if ((size = a.length) != 0) { if (c.getClass() == ArrayList.class) { elementData = a; } else { elementData = Arrays.copyOf(a, size, Object[].class); } } else { // replace with empty array. elementData = EMPTY_ELEMENTDATA; } }
4. add(Object o)扩容
add(Object o) 首次扩容为 10,再次扩容为上次容量的 1.5 倍(使用移位相加的规则即( 原 容 量 > > 1 ) + 原 容 量 (原容量>>1)+ 原容量(原容量>>1)+原容量 )
无参构造ArryList()
首次添加元素a
当数组容量满时添加b
代码演示:
演示扩容10次的ArrayList的长度
import java.util.ArrayList; import java.util.List; public class TestArrayList { public static void main(String[] args) { System.out.println(arrayListGrowRule(10)); } 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]
5. addAll(Collection c) 扩容
addAll(Collection c) 没有元素时,扩容为 Math.max(10, 实际元素个数),有元素时为 Math.max(原容量 1.5 倍, 实际元素个数)
代码演示:
无初始容量时扩容
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; // --add-opens java.base/java.util=ALL-UNNAMED public class TestArrayList { public static void main(String[] args) { testAddAllGrowEmpty(); } private static void testAddAllGrowEmpty() { ArrayList<Integer> list = new ArrayList<>(); list.addAll(List.of(1, 2, 3)); // list.addAll(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); 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; } } } //当执行 list.addAll(List.of(1, 2, 3)); 时运行结果为:10 //当执行 list.addAll(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); 时结果为:11
有初始容量(10) 时扩容
import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; // --add-opens java.base/java.util=ALL-UNNAMED public class TestArrayList { 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); } list.addAll(List.of(1, 2, 3)); // list.addAll(List.of(1, 2, 3, 4, 5, 6)); 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; } } } //当执行 list.addAll(List.of(1, 2, 3)); 时运行结果为:15 //当执行 list.addAll(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)); 时结果为:16