ArrayList是可增长数组,当存储的数组不足时,根据capacity值进行创建新的增长后的数组,然后将旧的数组拷贝到新的数组中。查找快,增删慢的特性。
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
// 默认的容量
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 数组内容
transient Object[] elementData;
// 数组大小
private int size;
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);
}
}
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
this.elementData = EMPTY_ELEMENTDATA;
}
}
复制代码
public boolean add(E e) {
ensureCapacityInternal(size + 1); // size+1 是需要的长度,进行判断大小是否足够,也是最小的需要的容量
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// 需要的最小长度,如果大于现有的长度,则增长
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity) {
// 增长旧的容量的一般
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
// 如果最小的需要容量比现有的再增长一般还要高 ,则按照minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
// 一般 这里都是负值
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// 生成新数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
复制代码
public E remove(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
modCount++;
E oldValue = (E) elementData[index]; // 获取到remove的元素,
int numMoved = size - index - 1;
if (numMoved > 0)// 向前复制移动一位
System.arraycopy(elementData, index+1, elementData, index,numMoved);
elementData[--size] = null;// 最后一个元素为null
return oldValue;
}
}
复制代码
linkedList 是一个链表,增删快,查找慢的特性。双链表 每个节点都有指向前一个和下一个节点的引用。
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
// 持有到尾节点的引用
final Node<E> l = last;
//创建新的节点 ,初始化前节点,value,next节点为null。
final Node<E> newNode = new Node<>(l, e, null);
// last节点指向新节点。
last = newNode;
// 如果第一个元素,last 和first节点都是新节点
// 否则 让前一个节点的next指向新节点
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
复制代码
public E remove(int index) {
return unlink(node(index));
}
// 查找到index上的元素
Node<E> node(int index) {
// 如果index 小于size的一半,从头开始查找,
// 否则 从末尾开始查找
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
// 通过next,不停的找到下一个对象
x = x.next;
return x;
} else {
// 从尾部 递减
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
// 找到该节点后,获取 该节点的前一个和下一个节点。
E unlink(Node<E> x) {
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
// 如果前一个节点为null,则该节点是第一个节点,
if (prev == null) {
first = next;
} else {
// 将前一个节点的next指向下一个节点
prev.next = next;
x.prev = null;
}
// next 为null 则是尾节点,last则是前一个节点
if (next == null) {
last = prev;
} else {
// next的前一个等于前一个
next.prev = prev;
x.next = null;
}
//
x.item = null;
size--;
modCount++;
return element;
}
复制代码
#include <malloc.h>
template<class E>
class ArrayList {
private:
// 长度,数组,当前角标
E *array = NULL;// 当前数组的指针
int len = 0;// 数组大小
int index = 0;// 当前角标
public:
ArrayList();
ArrayList(int len);
void add(E e);
E remove(int index);
E get(int index);
~ArrayList();
int size();
// 拷贝构造函数
private:
void ensureCapacityInternal(int capacity);
void grow(int capacity);
};
//-------------------- 实现 -----------------------//
template<class E>
ArrayList<E>::ArrayList() {}
// 每次实现方法都得添加
template<class E>
ArrayList<E>::ArrayList(int len) {
if (len <= 0) {
return;
}
this->len = len;
this->array = (E *) malloc(sizeof(E) * len);
}
template<class E>
ArrayList<E>::~ArrayList() {
if (this->array) {
free(this->array);
this->array = NULL;
}
}
template<class E>
int ArrayList<E>::size() {
return this->index;
}
template<class E>
void ArrayList<E>::add(E e) {
ensureCapacityInternal(index + 1); // Increments modCount!!
this->array[index++] = e;
}
template<class E>
void ArrayList<E>::ensureCapacityInternal(int capacity) {
if (this->array == NULL) {
capacity = 10;
}
if (capacity - len > 0) {
// 创建新的数组
grow(capacity);
}
}
// 扩容数组的大小
template<class E>
void ArrayList<E>::grow(int capacity) {
// 扩容
int new_len = len + (len >> 1);
if (capacity - new_len > 0) {
new_len = capacity;
}
// 创建新的数组
E *new_arr = (E *) malloc(sizeof(E) * new_len);
if (this->array) {
// 原来的数据拷贝进来
memcpy(new_arr,this->array, sizeof(E) * index);// sizeof(E)*index 字节
free(this->array);// 内存泄漏
}
this->array = new_arr;
this->len = new_len;
}
template<class E>
E ArrayList<E>::get(int index) {
return this->array[index];
}
template<class E>
E ArrayList<E>::remove(int index) {
// 自己做 remove 和 拷贝构造函数
}
复制代码