(1)ArrayList的初始化
public ArrayList() {
super();
this.elementData = EMPTY_ELEMENTDATA;
}
会为elementData赋值一个空的Object数组,长度为0
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}
如果传一个参数的时候就是设置初始的容量,不能小于0
(2)添加
添加第一个
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++; //暂且不管是什么意思
//这个minCapacity是元素下标+1,即当前存在元素的数量
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
如果添加元素时,是默认没有初始化容量的ArrayList,就会初始化为容量为10
然后在新添加的元素添加之后,如果超出容量范围的话,就会进行扩容
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);
}
这里对数组进行扩容,新的容量是原来容量的1.5倍
这个时候对数组进行扩容,即把原来数组的内容复制到一个新的容量为newCapacity的数组中
(3)删除:remove(Object obj) 和remove(index)
public E remove(int index) {
rangeCheck(index);//判断下标是否合法
modCount++;
E oldValue = elementData(index);//把elementData数组相应下标的值找出来
int numMoved = size - index - 1;//确定要移动多少个,即被删除掉的元素后的所有元素
if (numMoved > 0)//其实等于0的时候,相当于删除掉了最后一个的元素
System.arraycopy(elementData, index+1, elementData, index,
numMoved);//对数组本身进行操作,把第index+1之后的值,都移动到index处,即向前移动了一个
elementData[--size] = null; // clear to let GC do its work 把最后一个值赋值为null
return oldValue;//返回删除掉的值
}
删除的时候会返回删除的值
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
与remove相应坐标的不同是,无非是判断每一个值,看哪一个值一样
但其实只能删除掉第一个相同的值
(4)获取:get(index)
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
会判断该index是否合法,然后返回数组相应index的位置即可
2、关于Vector
其实经过仔细的观察之后,发现Vector与ArrayList在实际的操作上几乎是一样的
但是我发现Vector的方法都有synchronized修饰的,表示这是线程安全的
其他的区别就是在初始化的时候不一样,请看我的分析
public Vector() {
this(10);
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
如果没有初始化时的参数,会默认给一个10,我很惊讶
如果给定了初始化的参数,就按给定的值进行初始化;
还有第二个参数,控制的是每次扩容时候的增加的值;
扩容的方法与ArrayList是相似的,只不过ArrayList是扩容1.5倍,
而Vector是按照指定的扩容值扩容的;如果不设置的话,其实就是增加二倍
3、关于LinkedList
(1)初始化
构造方法里竟然什么都没有,我惊呆了。。。
(2)添加
public boolean add(E e) {
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last; //把last的值赋给l,last初始为null,会根据添加的情况改变
final Node<E> newNode = new Node<>(l, e, null);//新建一个节点,其实新节点都是最后一个节点,所以next是null
last = newNode;//这个时候last就是这个新添加的节点了,以供下一个节点添加的使用
if (l == null)//如果last是null的话,这个节点很明显就是第一个节点
first = newNode;
else //如果不是第一个节点的话,那么它的前一个节点的next就是这个节点了
l.next = newNode;
size++;//大小++
modCount++;
}
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;
}
}
(3)删除
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
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;
}