一、Vector
1、Vector的结构
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializabl
{
我们知道Vector与ArrayList比较其是线程安全的,我们可以看到这个与ArrayList一样实现了RandomAccess(因为其也是通过数组实现)。
2、成员变量
1)、elementCount
protected Object[] elementData;
这个与ArrayList的size类似,就是用来表明有多少个元素的。
2)、elementData
protected Object[] elementData;
这个就是用来放元素的数组
3)、capacityIncrement
protected int capacityIncrement;
这个应该是ArrayList没有的这个变量,这个成员变量是表明在扩容的时候扩大多少(ArrayList
一般是默认原来的1.5)。
3、构造方法
1)、Vector(int initialCapacity, int capacityIncrement)
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
2)、Vector(int initialCapacity)
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
这里是调用1的方法,不过capacityIncrement默认传的是0。
3)、Vector()
public Vector() {
this(10);
}
这个又是对第一个构造函数的补充默认,其的initialCapacity初始化数组的大小是10(ArrayList的DEFAULT_CAPACITY也是10)。其还有一个初入Collection去初始化创建一个Vector(Vector(Collection<? extends E> c))。
4、主要方法
我们在前面有讲过,Vector与ArrayList主要不同点是Vector是线程安全的,这是因为其暴露出来供使用的方法都是加了synchronized来同步的,所以其是线程安全的。但我们知道synchronized是一种很重的锁,所以JDK提供了concurrent包,来减少对应的颗粒度,这个我们到时候再来梳理学习。
1)、trimToSize()
public synchronized void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}
这个方法就是缩减elementData数组的长度,将其变为elementCount长度的数组,来减少没有使用到的浪费的空间。
2)、grow(int minCapacity)
private Object[] grow(int minCapacity) {
return elementData = Arrays.copyOf(elementData,
newCapacity(minCapacity));
}
这个就是根据一个最小的容量minCapacity去扩容创建copy一个新数组,不过可以看到其主要工作的是newCapacity(minCapacity)方法。
3)、newCapacity
private int newCapacity(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity <= 0) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return minCapacity;
}
return (newCapacity - MAX_ARRAY_SIZE <= 0)
? newCapacity
: hugeCapacity(minCapacity);
}
这个其实与ArrayList的类似,特别是在最后面的一个return的逻辑。但这里主要的扩容逻辑还是不同,这里的扩容是判断capacityIncrement(可以自己设置)有没有主动设置,如果有,则是再增加capacityIncrement的长度,如果没有则是则是原来双倍的容量(不是像原来ArrayList一样是向右移一位)。
这个Vector其他的一些方法增删改查大部分与ArrayList是类似的,这里就不再梳理了,主要是在前面加了synchronized字段。
二、ArrayDeque
这个是用数组的形式对Deque接口的方法实现,类似与上一篇文章用链表的形式对Deque接口的实现。
1、结构
public class ArrayDeque<E> extends AbstractCollection<E>
implements Deque<E>, Cloneable, Serializable
可以看到其是继承了AbstractCollection类。
2、变量
1)、elements
transient Object[] elements;
存放元素的数组。
2)、head
transient int head;
队首元素的位置。
3)、tail
transient int tail;
队尾元素的位置。
3、构造方法
1)、ArrayDeque()
public ArrayDeque() {
elements = new Object[16];
}
可以看到其的初始化数组大小是16。
2)、ArrayDeque(int numElements)
public ArrayDeque(int numElements) {
elements =
new Object[(numElements < 1) ? 1 :
(numElements == Integer.MAX_VALUE) ? Integer.MAX_VALUE :
numElements + 1];
}
这个是根据入参numElements来决定大小的,然后小于1,则用1替代。
同样其也有Collection形式的构造方法ArrayDeque(Collection<? extends E> c)。
三、Stack
这个有名称也可以看到其是栈结构,同时其的方法是线程安全的。
1、结构&构造方法
public
class Stack<E> extends Vector<E> {
public Stack() {
}
我们可以看到其是直接继承的继承Vector。
2、方法
1)、push(E item)
public E push(E item) {
addElement(item);
return item;
}
这个是push添加元素的方法,其直接调用的Vector的addElement(item)方法。
2)、pop()
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
这个是出栈,然后也是调用的removeElementAt方法。同时可以看到这个是线程安全的。这个是出栈操作,所以其会将现在该位置的内容删除调。
3)、peek()
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
这个方法也是获取栈顶的日弄,不过可以看到其是调用的elementAt方法,这个方法就是获取该位置的值,而并不会删除栈顶的值。