ArrayList 是一个动态数组, 线程不安全 , 允许元素为 null.
ArrayList 的数据结构是数组, 查询比较方便.
ArrayList 类的接口
- public class ArrayList<E> extends AbstractList<E>
- implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
RandomAccess:RandmoAccess 是一个标记接口, 用于被 List 相关类实现. 他主要的作用表明这个相关类支持快速随机访问. 在 ArrayList 中, 我们即可以通过元素的序号快速获取元素对象 -- 这就是快速随机访问. 除了 List 的 "快速随机访问", 还可以 "通过 Iterator 迭代器访问".
Cloneable: 实现该接口的类可以对该类的实例进行克隆 (按字段进行复制).
Serializable:ArrayList 支持序列化, 能通过序列化去传输.
构造方法
ArrayList(), 初始化的时候, 先分配一个空数组. 添加一个元素时, 容量就会扩展到 DEFAULT_CAPACITY, 也就是 10.
- /**
- * Constructs an empty list with an initial capacity of ten.
- */
- public ArrayList() {
- this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
- }
- /**
- * Shared empty array instance used for default sized empty instances. We
- * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
- * first element is added.
- */
- private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
- /**
- * The array buffer into which the elements of the ArrayList are stored.
- * The capacity of the ArrayList is the length of this array buffer. Any
- * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
- * will be expanded to DEFAULT_CAPACITY when the first element is added.
- *
- * 初始化的时候, 分配一个空数组. 添加一个元素时, 容量就会扩展到 DEFAULT_CAPACITY, 也就是 10.
- * 关键字 transient 表示属性不会被序列化.
- */
- transient Object[] elementData; // non-private to simplify nested class access
- /**
- * Default initial capacity.
- * 默认容量为 10
- */
- private static final int DEFAULT_CAPACITY = 10;
往 ArrayList 中添加数据的方法 add() 如下:
- /**
- * Appends the specified element to the end of this list.
- *
- * @param e element to be appended to this list
- * @return <tt>true</tt> (as specified by {@link Collection#add})
- */
- public boolean add(E e) {
- // 扩容
- ensureCapacityInternal(size + 1); // Increments modCount!!
- elementData[size++] = e;
- return true;
- }
扩容时, ensureCapacityInternal() 方法内部调用的是 grow() 方法.
数组扩容. 如果插入数据时容量不够, 就将容量扩大为 1.5 倍.
扩容的过程就是数组拷贝 Arrays.copyOf 的过程, 每一次扩容就会开辟一块新的内存空间和数据的复制移动
grow() 方法 如下所示:
- /**
- * Increases the capacity to ensure that it can hold at least the
- * number of elements specified by the minimum capacity argument.
- *
- * @param minCapacity the desired minimum capacity
- */
- private void grow(int minCapacity) {
- // overflow-conscious code
- int oldCapacity = elementData.length;
- // 左移一位表示原来的 0.5 倍, 以下是将容量扩大为 1.5 倍
- int newCapacity = oldCapacity + (oldCapacity>> 1);
- if (newCapacity - minCapacity <0)
- newCapacity = minCapacity;
- if (newCapacity - MAX_ARRAY_SIZE> 0)
- newCapacity = hugeCapacity(minCapacity);
- // minCapacity is usually close to size, so this is a win:
- // 复制数组
- elementData = Arrays.copyOf(elementData, newCapacity);
- }
get(int index) 方法很简单, 就是检查一下小心数组越界, 然后根据下标返回数组元素
- /**
- * Returns the element at the specified position in this list.
- *
- * @param index index of the element to return
- * @return the element at the specified position in this list
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- public E get(int index) {
- rangeCheck(index);
- return elementData(index);
- }
- @SuppressWarnings("unchecked")
- E elementData(int index) {
- return (E) elementData[index];
- }
参考博客 :
https://www.jianshu.com/p/02f8696bf4cf
来源: http://www.bubuko.com/infodetail-2958441.html