导读:ArrayList数组集合在开发中是使用频率很高的数据结构,这个类是如何实现的呢,它的特点是什么呢,适用于什么样的场景呢?
类核心成员
- DEFAULT_CAPACITY 默认长度10
- elementData Oject类型数组
- size 数组长度
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final int DEFAULT_CAPACITY = 10;
transient Object[] elementData;
private int size;
}
本质
是一个Object类型的数组,数组的元素默认值为null
主要方法的解读
新增的元素赋值到数组的尾部,所以新增的时间复杂度为O(1)。
ensureCapacityInternal方法会判断这个数组链表是否需要扩容,如果满足扩容条件,则声明一个两倍长度的新数组,并从新赋值。扩容操作会提高代码执行时间,降低效率。所以在使用数组集合时候尽量预估数组的长度。
public boolean add(E e) {
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
第一中方式:输入下标删除,直接赋值为null。时间赋值度为O(1)
第二中方式:输入元素删除,遍历判断,删除第一个符合条件的元素。时间复杂度为O(n)
//通过下标删除
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null;
return oldValue;
}
//通过元素删除
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
修改方法set(),赋值对应下标元素值 。时间复杂度O(1)
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
get()方法使用的是node方法获取元素。时间复杂度O(1)
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
add(int index, E element)。System.arraycopy方法是底层语言实现的,采用了while遍历。时间复杂度为O(n)。
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
总结
操作 | 新增 | 删除 | 修改 | 查询 | 插入 |
时间复杂度 | O(1) | O(n) | O(1) | O(1) | O(n) |
特点
- 需要一块地址连续的内存,对内存要求高。
- 数组链表有序
- 新增/修改/查询操作效率高。
应用场景
使用于修改/查询操作频率高的场景