List
ArrayList
默认容量:10,最大容量:231 - 8 ~ 231 - 1,其中还需要看JVM运行时的具体内存。存储的本质是对象数组。
private static final int DEFAULT_CAPACITY = 10;
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
扩容:扩容是在原先的基础上加原来的一半(1.5倍),当容量扩容后如果恰好大于设定的值(2^31 - 9)则扩容为231-1否则容量扩大至231 - 9。在执行添加或构造时会调用 ensureCapacityInternal(int minCapacity)
方法,确定容量,如果容量不足则调用 grow(int minCapacity)
方法。
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
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);
}
查找:使用indexOf的时候会先判断参数是否为null,为空则比较null,否则拿参数的equals方法比较元素,故可以向数组中填null
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
删除:将删除元素后的所有元素向前移动,使用了 System.arraycopy
方法。
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; // clear to let GC do its work
return oldValue;
}
克隆方法:仅仅进行浅复制,不调用存储元素的copy方法
/**
* Returns a shallow copy of this <tt>ArrayList</tt> instance. (The
* elements themselves are not copied.)
*
* @return a clone of this <tt>ArrayList</tt> instance
*/
public Object clone() {
try {
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
LinkedList
默认容量:0,最大容量根据堆内存的大小决定。本质是双向链表,分别记录了头指针和尾指针。
transient int size = 0;
transient Node<E> first;
transient Node<E> last;
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
移除:移除很有个性,先将first/last赋值给了f/l,然后才对first/last进行移除
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
查找:拿到首结点挨个遍历,写法与 ArrayList
类似,都是先判断待查找的对象是否为 null
,不将 null
判断写入循环内的好处是在循环内减少了很多的判断。
public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
克隆方法:同 ArrayList
,仅仅进行浅复制,不调用存储元素的copy方法
/**
* Returns a shallow copy of this {@code LinkedList}. (The elements
* themselves are not cloned.)
*
* @return a shallow copy of this {@code LinkedList} instance
*/
public Object clone() {
LinkedList<E> clone = superClone();
// Put clone into "virgin" state
clone.first = clone.last = null;
clone.size = 0;
clone.modCount = 0;
// Initialize clone with our elements
for (Node<E> x = first; x != null; x = x.next)
clone.add(x.item);
return clone;
}
Vector
线程安全的,需要对成员变量进行操作的每个操作的方法都加入了 synchronized
关键字