《java collections》 学习笔记
当需要一个动态增长且不知道最终size
的数组时,Vector
派上用场了。
作为Vector的补充(子类),Stack
作为一个先入后出
的数据结构出现了。
(Stack extends Vector
)
RandomAccess 接口的作用
Vector 实现了RandmoAccess接口,即提供了随机访问功能
。
在Vector中,我们即可以通过元素的序号
快速获取元素对象;这就是快速随机访问
。
/*
* for (int i=0, n=list.size(); i < n; i++)
* list.get(i);
* runs faster than this loop:
* for (Iterator i=list.iterator(); i.hasNext(); )
* i.next();
*/
public interface RandomAccess {
}
Vector
Vector是动态增长且线程安全的数据结构。
任意类型的Object对象都可以存放在Vector,但是原始类型数据是不能存放
在Vector中的,但是由于自动装箱
功能,并不会抛出异常.
Vector v = new Vector();
v.add(1);
v.add('c');
v.add("kitty");
System.out.println(v.get(0).getClass()); // class java.lang.Integer
System.out.println(v.get(1).getClass()); // class java.lang.Character
System.out.println(v.get(2).getClass()); // class java.lang.Character
自动装箱,拆箱
Integer a1 = 1; int a2 = 1; Integer a3 = 128; int a4= 128; Integer a5 = 128; System.out.println(a1 == a2); //true System.out.println(a3 == a4); //true System.out.println(a3 == a5); //false
Vector的构造函数
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
//保存数据的数组
protected Object[] elementData;
//实际的元素的个数
//elementData首、尾元素为: elementData[0] ~ elementData[elementCount-1]
protected int elementCount;
//每次数组增长的长度,当数组可用空间不够用时,会自动增长
//1*capacityIncrement ,2*capacityIncrement,, n*capacityIncrement
//如果未设置capacityIncrement时,数组增长策略为:elementData.length * 2;
protected 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;
}
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
public Vector() {
this(10);
}
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
//设置实际元素的个数
elementCount = elementData.length;
// c.toArray might (incorrectly) not return Object[]
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
}
Adding Elements
增长策略
private void ensureCapacityHelper(int minCapacity) {
// 当需要的最小长度 > 大于数组的长度时,则进行grow操作
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
//如果未配置capacityIncrement,则每次都扩容至当前数组长度的2倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
//若增长后的长度,仍小于minCapacity,则设置最终的长度为:minCapacity
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
//特殊处理...略
newCapacity = hugeCapacity(minCapacity);
//数组拷贝System.arraycopy(elementData, 0, newElementData, 0,original.length);
elementData = Arrays.copyOf(elementData, newCapacity);
}
Adding at the End
新增元素的方法都是线程安全的synchronized
public synchronized boolean add(E e) {
//modCount继承自父类AbstractList中的属性,用来记录当前Vector发生实际元素长度发生变更的次数:增加、删除操作。
modCount++;
ensureCapacityHelper(elementCount + 1);
//等价于: elementData[elementCount] = e; elementCount++;
elementData[elementCount++] = e;
return true;
}
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
modCount:继承自父类AbstractList中的属性,用来记录当前Vector发生实际元素长度发生变更的次数:增加、删除操作。
Adding in the Middle
public void add(int index, E element) {
insertElementAt(element, index);
}
public synchronized void insertElementAt(E obj, int index) {
modCount++;
//index 必须为[0,elementCount]区间内的一个位置
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
ensureCapacityHelper(elementCount + 1);
//分段copy, 将index之后的元素后移1位
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
//设置index位置的元素为obj
elementData[index] = obj;
elementCount++;
}
Adding Another Collection
public synchronized boolean addAll(Collection<? extends E> c) {
modCount++;
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityHelper(elementCount + numNew);
//将a的[0,numNew]元素,拷贝至elementData的[elementCount,+oo)位置
System.arraycopy(a, 0, elementData, elementCount, numNew);
elementCount += numNew;
return numNew != 0;
}
public synchronized boolean addAll(int index, Collection<? extends E> c) {
modCount++;
if (index < 0 || index > elementCount)
throw new ArrayIndexOutOfBoundsException(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityHelper(elementCount + numNew);
int numMoved = elementCount - index;
if (numMoved > 0)
//首先将elementData中,index位置之后的`所有`元素向后移动 numNew个位置
//需要移动的元素的个数为[index,elementCount-index]
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
//然后将a[0,numNew]个元素插入elementData[index,...]之后的位置
System.arraycopy(a, 0, elementData, index, numNew);
elementCount += numNew;
return numNew != 0;
}
Removing Elements
删除所有元素
public void clear() {
removeAllElements();
}
public synchronized void removeAllElements() {
modCount++;
for (int i = 0; i < elementCount; i++)
// 将所有元素设置为null,清除引用
elementData[i] = null;
elementCount = 0;
}
删除单个元素(by index)
//返回被删除的值
public synchronized E remove(int index) {
modCount++;
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
//
E oldValue = elementData(index);
int numMoved = elementCount - index - 1;
if (numMoved > 0)
//elementData[index+1,elementCount),移动至[index,elementCount-1)
//移动的个数为: numMoved = elementCount-index-1;
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
//当前数组元素个数仍为elementCount,
//elementCount-1 位置的元素为待删除元素;
elementData[--elementCount] = null;
return oldValue;
}
//无返回值
public synchronized void removeElementAt(int index) {
modCount++;
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
else if (index < 0) {
throw new ArrayIndexOutOfBoundsException(index);
}
int j = elementCount - index - 1;
if (j > 0) {
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
elementData[elementCount] = null;
}
删除单个元素(by Object)
public boolean remove(Object o) {
return removeElement(o);
}
public synchronized boolean removeElement(Object obj) {
modCount++;
//寻找index
int i = indexOf(obj);
if (i >= 0) {
//按照index 删除
removeElementAt(i);
return true;
}
return false;
}
public int indexOf(Object o) {
return indexOf(o, 0);
}
//index位置开始查找
public synchronized int indexOf(Object o, int index) {
if (o == null) {
//[index,elementCount) ,第一个为null的位置
for (int i = index ; i < elementCount ; i++)
if (elementData[i]==null)
return i;
} else {
//[index,elementCount) ,第一个.equals(o)的位置
for (int i = index ; i < elementCount ; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
删除集合: removeAll(Collection)
保留指定集合:retaining(Collection)
removeRange
protected synchronized void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = elementCount - toIndex;
//将[toIndex,+oo] 元素 移动至 [fromIndex,+oo]
//+oo:为需要移动的元素的个数: elementCount - toIndex
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
//将移动最末尾: toIndex-fromIndex个元素置为null
//他们对应的index为: elementCount - (toIndex-fromIndex)
int newElementCount = elementCount - (toIndex-fromIndex);
while (elementCount != newElementCount)
elementData[--elementCount] = null;
}
Replacing Elements
//带返回值
public synchronized E set(int index, E element) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
//无返回值
public synchronized void setElementAt(E obj, int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
elementData[index] = obj;
}
Sizing Elements
//返回数组的容量
public synchronized int capacity() {
return elementData.length;
}
//返回实际元素的个数
public synchronized int size() {
return elementCount;
}
//实际元素个数 == 0
public synchronized boolean isEmpty() {
return elementCount == 0;
}
public synchronized void setSize(int newSize) {
modCount++;
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
//如果newSize < elementCount, 将超出newSize部分的元素丢弃
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
elementCount = newSize;
}
Vector Immutability
Vector v = new Vector();
// 填充vector....略...
List l = Collections.unmodifiableList(v);
获取元素
根据index获取
E elementData(int index) {
return (E) elementData[index];
}
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
根据位置获取(first,last)
public synchronized E firstElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}
public synchronized E lastElement() {
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}
枚举元素
public Enumeration<E> elements() {
return new Enumeration<E>() {
int count = 0;
//当count < elementCount,说明仍有元素...
public boolean hasMoreElements() {
return count < elementCount;
}
public E nextElement() {
synchronized (Vector.this) {
if (count < elementCount) {
return elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
查找元素位置
public int indexOf(Object element)
//自index之后,第一次发现element的位置
public int indexOf(Object element, int index)
public int lastIndexOf(Object element)
//自index之后,最后一次发现element的位置
public int lastIndexOf(Object element, int index)
其他API
equals
equals方法由父类AbstractList
实现。
//AbstractList
public boolean equals(Object o) {
if (o == this)
return true;
if (!(o instanceof List))
return false;
ListIterator<E> e1 = listIterator();
ListIterator<?> e2 = ((List<?>) o).listIterator();
//this[i].equals(o[i]) ; 每一个对应index的元素都equals.
while (e1.hasNext() && e2.hasNext()) {
E o1 = e1.next();
Object o2 = e2.next();
if (!(o1==null ? o2==null : o1.equals(o2)))
return false;
}
//这一行代码:判断e1.length == e2.length ?
return !(e1.hasNext() || e2.hasNext());
}
copyInto
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
clone
public synchronized Object clone() {
try {
Vector<E> v = (Vector<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, elementCount);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
throw new InternalError(e);
}
}
Serializing
Vector自身实现了Serializable
接口,但是这并不表明它就可以序列化。
Vector可序列化的前提是:它的所有元素都实现了Serializable接口,
Stack
Stack(栈)继承Vector.
Stack是一个last−in, first−out (LIFO) 数据结构。
Stack源码分析
Stack继承自Vetor,绝大多数功能依赖Vector中方法实现,Stack自身的代码逻辑相对简单,这里整体大致分析下:
class Stack<E> extends Vector<E> {
public Stack() {
}
//元素入栈
public E push(E item) {
addElement(item);
return item;
}
//栈顶元素出栈: 返回Vector最后一个元素,并移除
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
//获取栈顶元素(不移除):返回Vector最后一个元素
public synchronized E peek() {
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
public boolean empty() {
return size() == 0;
}
//寻找元素,
public synchronized int search(Object o) {
//寻找最后一次出现o的位置
int i = lastIndexOf(o);
if (i >= 0) {
//size():由父类Vector实现,返回elementCount
//last-in,first-out数据结构,所以在elementData[i] 在Stack相对位置为 elementCount - i;
return size() - i;
}
return -1;
}
}