参考文章:JCFInternals
JDK:1.9
介绍:
ArrayList实现了List接口,是顺序容器,即元素存放的数据与放进去的顺序相同,允许放入null元素,底层通过数组实现,未实现同步。
实现功能:
- size():得到当前集合元素个数
- isEmpty():判断集合是否为空
- get(int index):获得指定位置集合
- set(int index, T element):将指定位置集合设置为指定值
- add(T element):向集合添加一个元素
- add(int index, T element):向集合指定下标添加指定元素
- remove(int index):移除指定下标的元素
- remove(Object o):移除集合中第一次出现的指定元素
代码
import java.util.*;
public class MyArrayList<T> {
Object[] elementData;
private int size;
public static final int DEFAULT_CAPACITY = 10;
public static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE;
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 初始化elementData
MyArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// 下标越界检查
private boolean rangeCheck(int index) {
if (index < 0 || index > size) {
throw new RuntimeException("下标越界!");
}
return true;
}
// 扩容
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
// 扩容 1.5 倍
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
if (newCapacity - MAX_ARRAY_SIZE > 0) {
newCapacity = (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
// 扩容
elementData = Arrays.copyOf(elementData, newCapacity);
}
public int size() {
return size;
}
public boolean isEmpty() {
return 0 == size;
}
public T get(int index) {
// 下标越界检查
rangeCheck(index);
return (T) elementData[index];
}
public T set(int index, T element) {
// 下标越界检查
rangeCheck(index);
// 取到将要被覆盖的值
T oldElement = (T) elementData[index];
// 指定位置赋值
elementData[index] = element;
// 返回被覆盖的值
return oldElement;
}
public void add(T element) {
// 检查容量
if (size == elementData.length) {
// 满了就扩容
grow(size + 1);
}
add(size, element);
}
public void add(int index, T element) {
// 下标越界检查
rangeCheck(index);
// 检查容量
if (size == elementData.length) {
// 满了就扩容
grow(size + 1);
}
System.arraycopy(elementData, index, elementData, index + 1, size - index);
elementData[index] = element;
size++;
}
public T remove(int index) {
// 下标越界检查
rangeCheck(index);
T oldElement = (T) elementData[index];
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
return oldElement;
}
private void fastRemove(int index) {
int numMoved = size - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
}
elementData[--size] = null;
}
public boolean remove(Object o) {
if (o == null) {
for (int i = 0; i < size; i++) {
if (elementData[i] == null) {
fastRemove(i);
return true;
}
}
} else {
for (int i = 0; i < size; i++) {
if (elementData[i].equals(o)) {
fastRemove(i);
return true;
}
}
}
return false;
}
}