ArrayList 源码
1、构造方法,无参和有参的,有参构造方法,可以指定数组初始容量大小
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
//大于0,设置初始化大小
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
//等于0,设置为空数组
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
无参构造
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
2、add方法
public boolean add(E e) {
//添加都最后
ensureCapacityInternal(size + 1);
elementData[size++] = e;
return true;
}
确定数组的元素个数
private void ensureCapacityInternal(int minCapacity) {
//如果是默认的空数组,第一次添加元素
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
//比较默认容量(10)和需要添加后元素最下的容量
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) {
// overflow-conscious code
int oldCapacity = elementData.length;
//扩容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()方法
public E get(int index) {
//检验下标 index>=size 报异常
rangeCheck(index);
return elementData(index);
}
//返回数据
E elementData(int index) {
return (E) elementData[index];
}
LinkedList源码
1、add方法
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
//旧的最后节点的next是新节点
l.next = newNode;
size++;
modCount++;
}
2、get方法
public E get(int index) {
//校验小标,必须index >= 0 && index < size
checkElementIndex(index);
//获得指定index的对应的节点值
return node(index).item;
}
Node<E> node(int index) {
// assert isElementIndex(index);
//如果index在前半段,从前面开始往找
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
//index在后半段,从后面开始往前找
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}
3、remove(int index)方法
public E remove(int index) {
//校验小标,必须index >= 0 && index < size
checkElementIndex(index);
//删除节点,重新组装链表
return unlink(node(index));
}
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) {
//设置首节点是next
first = next;
} else {
//前一个节点不是null,前一个节点的下一个节点是删除节点的下一个节点
prev.next = next;
//设置本节点前一个是null,和前面断开
x.prev = null;
}
//后一个节点是null
if (next == null) {
//设置尾结点为删除节点的前一个节点
last = prev;
} else {
//不为空,下一个节点的前一个节点是删除节点的前一个节点
next.prev = prev;
//设置本节点的后一个为null,和后面断开
x.next = null;
}
//设置节点数据值为null
x.item = null;
//节点数减一
size--;
modCount++;
return element;
}
4、remove(Object o)方法
public boolean remove(Object o) {
//删除的节点值是null的
if (o == null) {
//循环整个链表
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
//删除这个节点,重新组装
unlink(x);
return true;
}
}
} else {
//删除节点值不为null
for (Node<E> x = first; x != null; x = x.next) {
//比较节点数据值和删除的值 是否相等
if (o.equals(x.item)) {
//删除这个节点,重新组装
unlink(x);
return true;
}
}
}
return false;
}