#ArrayList和LinkedList学习 ##1.ArrayList
###1.1源码分析 //默认数组容量即长度为10 private static final int DEFAULT_CAPACITY = 10;
//存储对象数组
transient Object[] elementData;
//数组长度
private int size;
//最大数组长度
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//为空的对象数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
//添加数据
public boolean add(E e) {
//检验数组长度
ensureCapacityInternal(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 void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
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 get(int index) {
//检验下标是否超过数组长度
rangeCheck(index);
return elementData(index);
}
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;
}
##2.LinkedList
###2.1源码分析
//链表长度
transient int size = 0;
//添加数据
public boolean add(E e) {
linkLast(e);
return true;
}
//添加数据到链表尾部
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
//表示链表为空
first = newNode;
else
//链表不为空,则当前尾节点的下一节点为新节点
l.next = newNode;
//链表长度加一
size++;
//操作数加一
modCount++;
}
//删除数据
public E remove(int index) {
//检验下标
checkElementIndex(index);
return unlink(node(index));
}
//根据下标获得节点
Node<E> node(int index) {
// >>:右移运算符,size >> 1,相当于size除以2的1次方
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
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) {
// assert x != null;
final E element = x.item;
final Node<E> next = x.next;
final Node<E> prev = x.prev;
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
//链表长度减一
size--;
//操作数加一
modCount++;
return element;
}
##3.比较
当读取数据时,采用ArrayList更快,因为是根据下标访问,时间为O(1),而
LinkedList会先遍历链表,才能找到下标代表的节点,时间为O(m)。
当写入,删除数据时,采用LinkedList更快,因为他通过修改头尾指针指向的对象,即可
完成添加,或者删除。而ArrayList则需要进行数组的拷贝。