ArrayList 源码解析
作者:前行
- 2023-09-13 广东
本文字数:2217 字
阅读完需:约 7 分钟
核心的属性
默认的初始化容量:private static final int DEFAULT_CAPACITY = 10;
空的数组实例:private static final Object[] EMPTY_ELEMENTDATA = {};
使用默认的容量大小空的数组实例:private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
缓冲数组:transient Object[] elementData; 第一次使用才初始化
ArrayList 的大小:private int size;
构造器
ArrayList 提供了多个构造器
// 无参构造方法,初始容量10public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
// 初始容量为设定值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); }}
// 通过集合初始化一个ArrayList// c不能为null,否则报 NPEpublic 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; }}
复制代码
数组拷贝
// java.util.Arrayspublic static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { @SuppressWarnings("unchecked") T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); // System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy;}
复制代码
存值方法 add()
public boolean add(E e) { modCount++; add(e, elementData, size); return true;}
private void add(E e, Object[] elementData, int s) { if (s == elementData.length) elementData = grow(); elementData[s] = e; size = s + 1;}
public boolean addAll(Collection<? extends E> c) { Object[] a = c.toArray(); modCount++; int numNew = a.length; if (numNew == 0) return false; Object[] elementData; final int s; if (numNew > (elementData = this.elementData).length - (s = size)) elementData = grow(s + numNew); System.arraycopy(a, 0, elementData, s, numNew); size = s + numNew; return true;}
复制代码
扩容方法 grow()
private Object[] grow() { return grow(size + 1);}
private Object[] grow(int minCapacity) { // 拷贝元素到新的数组中,底层调用的是 System.arraycopy方法 return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity));}
// 计算新的容量: 1.5倍的上一次的容量private int newCapacity(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity <= 0) { // 无参构造器初始化 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) return Math.max(DEFAULT_CAPACITY, minCapacity); if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return minCapacity; } return (newCapacity - MAX_ARRAY_SIZE <= 0) ? newCapacity : hugeCapacity(minCapacity);}
复制代码
无参构造的扩容
@Testvoid debugArrayList() { List<String> arrayList = new ArrayList<>(); // 第一次扩容 size=10 arrayList.add("1");
for (int i = 2; i <= 10; i++) { arrayList.add(""+i); } // 第二次扩容 size=15 arrayList.add("11");
for (int i = 12; i <= 15; i++) { arrayList.add(""+i); } // 第二次扩容 size=22 arrayList.add("16");}
复制代码
指定初始容量的扩容
@Testvoid debugArrayListWithInitialCap() { List<String> arrayList = new ArrayList<>(20); for (int i = 1; i <= 20; i++) { arrayList.add("" + i); } // 第一次扩容, int newCapacity = oldCapacity + (oldCapacity >> 1); // newCapacity =20+10=30 arrayList.add("21");
for (int i = 22; i <= 30; i++) { arrayList.add(""+i); } // 第二次扩容 size=30+15=45 arrayList.add("31");}
复制代码
取值方法 get()
public E get(int index) { Objects.checkIndex(index, size); return elementData(index);}
@SuppressWarnings("unchecked")E elementData(int index) { return (E) elementData[index];}
复制代码
经典错误
使用完 list 不做 clear
See Also
划线
评论
复制
发布于: 刚刚阅读数: 5
版权声明: 本文为 InfoQ 作者【前行】的原创文章。
原文链接:【http://xie.infoq.cn/article/415689c8da34547a22b307ab8】。文章转载请联系作者。
前行
关注
还未添加个人签名 2018-09-06 加入
还未添加个人简介










评论