版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/vi_young_95/article/details/83927098
Vector
简介
Vector
是一种实现了动态数组的集合,何为动态数组呢?即长度可以自动增长的数组,它是线程同步的,也就是说同一时刻只有一个线程可以写Vector
,可以避免多线程同时写引起的不一致性,但是比较消耗资源。接下来,我们来看Vector
的源码。
源码
public class Vector<E>
extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* 用于存放集合元素的数组对象
*/
protected Object[] elementData;
/**
* 数组中实际数据的长度
*/
protected int elementCount;
/**
* 数组的大小大于其该集合容量时,容量自动增加的量。
*/
protected int capacityIncrement;
/**
* 序列化id
*/
private static final long serialVersionUID = -2767605614048989439L;
/**
* 构造函数
* @param initialCapacity 初始大小
* @param capacityIncrement 每次扩容的大小
*/
public Vector(int initialCapacity, int capacityIncrement) {
super();
//如果初始长度小于0,抛出异常
if (initialCapacity < 0) {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
//new一个Object数组,长度为initialCapacity
this.elementData = new Object[initialCapacity];
//将每次扩容大小赋给类capacityIncrement
this.capacityIncrement = capacityIncrement;
}
/**
* 构造函数
* @param initialCapacity 初始大小
*/
public Vector(int initialCapacity) {
//默认扩容大小为0
this(initialCapacity, 0);
}
/**
* 无参构造
*/
public Vector() {
//默认初始大小为10
this(10);
}
/**
* 构造函数
* @param c 参数传入的是一个集合
*/
public Vector(Collection<? extends E> c) {
//首先将c转化为数组赋给elementData
elementData = c.toArray();
elementCount = elementData.length;
//如果该数组的类型不为Object[],则转换为Object[]
if (elementData.getClass() != Object[].class) {
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
}
/**
* 将集合复制到某个集合中
* @param anArray 复制的目标
*/
public synchronized void copyInto(Object[] anArray) {
System.arraycopy(elementData, 0, anArray, 0, elementCount);
}
/**
* 这里的意思是将多余的容量(即由于动态扩容导致的数组长度可能会大于数据的长度部分)删除
*/
public synchronized void trimToSize() {
modCount++;
//数组的长度
int oldCapacity = elementData.length;
//如果数据的长度小于数组的长度,将动态增长的部分去掉
if (elementCount < oldCapacity) {
elementData = Arrays.copyOf(elementData, elementCount);
}
}
/**
* 扩容方法
* @param minCapacity 需要的最小容量
*/
public synchronized void ensureCapacity(int minCapacity) {
//判断后,将修改值增加1
if (minCapacity > 0) {
modCount++;
ensureCapacityHelper(minCapacity);
}
}
/**
* 扩容桥方法
* @param minCapacity 需要的最小容量
*/
private void ensureCapacityHelper(int minCapacity) {
//如果需要的最小容量大于当前数组的长度,调用扩容方法
if (minCapacity - elementData.length > 0) {
grow(minCapacity);
}
}
/**
* 集合最大长度为Integer的最大值-8,
* 因为数组作为一个对象,需要一定的内存存储对象头信息,对象头信息最大占用内存不可超过8 byte
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 扩容方法实现
* @param minCapacity 需要的最小容量
*/
private void grow(int minCapacity) {
//获取当前数组的长度
int oldCapacity = elementData.length;
//如果设置了自动扩容的长度,就按照自动扩容的长度,否则翻倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
//如果新的长度小于该数组需要的最小长度,将该最小长度赋给newCapacity
if (newCapacity - minCapacity < 0) {
newCapacity = minCapacity;
}
//如果新的长度大于数组最大长度
if (newCapacity - MAX_ARRAY_SIZE > 0) {
//调用这个检查是否超过Integer的最大值,这里体现了设计的严谨,实际上这里很少会去调用
newCapacity = hugeCapacity(minCapacity);
}
//最后按照新的长度将数组信息拷贝到一个新的数组对象中后赋给原数组对象
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* 用于判断集合的值会不会溢出,一般很少会调用到这个方法
* @param minCapacity
* @return
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) {
throw new OutOfMemoryError();
}
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
/**
* 给该集合容器设置新的大小
* @param newSize
*/
public synchronized void setSize(int newSize) {
modCount++;
//如果设置的长度大于该数组的长度,进行扩容
if (newSize > elementCount) {
ensureCapacityHelper(newSize);
} else {
//反之将超出newSize的部分赋予null
for (int i = newSize ; i < elementCount ; i++) {
elementData[i] = null;
}
}
//将新的长度赋给数组的长度
elementCount = newSize;
}
/**
* 获取当前数组的长度
* @return 返回的是当前数组对象的长度
*/
public synchronized int capacity() {
return elementData.length;
}
/**
* 返回的是数组中数据的长度,因为由于动态扩容,数据的长度可能会小于数组的长度
* @return 返回的是数组中数组的长度
*/
@Override
public synchronized int size() {
return elementCount;
}
/**
* 判断集合中的元素个数是否为空
* @return 返回布尔值,为空返回true,不为空返回false
*/
@Override
public synchronized boolean isEmpty() {
return elementCount == 0;
}
/**
* 返回此集合的组件的枚举。返回的 Enumeration 对象将生成此向量中的所有项。生成的第一项为索引0处的项,然后是索引1处的项。
* @return 此集合的组件的枚举
*/
public Enumeration<E> elements() {
//返回的是一个内部类
return new Enumeration<E>() {
/**
* 枚举的索引
*/
int count = 0;
/**
* 是否有下一个枚举项
*/
@Override
public boolean hasMoreElements() {
return count < elementCount;
}
/**
* 获取下一个枚举项
* @return 返回的是下一位索引的枚举
*/
@Override
public E nextElement() {
synchronized (Vector.this) {
if (count < elementCount) {
//将索引+1
return elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
/**
* 判断集合中是否包含对象o
* @param o 判断集合中是否包含该对象
* @return 返回布尔值,包含返回true,不包含返回false
*/
@Override
public boolean contains(Object o) {
//通过indexOf判断是否存在该元素
return indexOf(o, 0) >= 0;
}
/**
* 判断集合中某个元素的索引位置
* @param o 用于判断位置的元素
* @return 返回该元素位于集合的索引值
*/
@Override
public int indexOf(Object o) {
return indexOf(o, 0);
}
/**
* 判断某个元素相对于某个索引开始的索引值
* @param o 用于判断的元素
* @param index 相对位置的索引
* @return 返回的是相对于index的索引值
*/
public synchronized int indexOf(Object o, int index) {
//分为两种情况进行判断为null和不为null
if (o == null) {
for (int i = index ; i < elementCount ; i++) {
if (elementData[i]==null) {
return i;
}
}
} else {
for (int i = index ; i < elementCount ; i++) {
if (o.equals(elementData[i])) {
return i;
}
}
}
//如果不存在,返回-1
return -1;
}
/**
* 返回某个元素最后一次出现在集合中的索引值
* @param o 用于判断位置的元素
* @return
*/
@Override
public synchronized int lastIndexOf(Object o) {
//基于某个索引的最后一次出现的位置索引,默认为最后一位
return lastIndexOf(o, elementCount-1);
}
/**
* 返回某个元素最后一次出现位置的索引
* @param o 用于判断位置的元素
* @param index 用于判断位置的相对索引
* @return 返回该判断元素相对于索引位置最后一次出现的位置的索引
*/
public synchronized int lastIndexOf(Object o, int index) {
//如果索引值大于数组长度,抛出一个异常
if (index >= elementCount) {
throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
}
//使用反向遍历,原理和indexOf一致
if (o == null) {
for (int i = index; i >= 0; i--) {
if (elementData[i]==null) {
return i;
}
}
} else {
for (int i = index; i >= 0; i--) {
if (o.equals(elementData[i])) {
return i;
}
}
}
//不存在,返回-1
return -1;
}
/**
* 返回该集合中某个索引位置的元素
* @param index 索引值
* @return 位于该集合中索引值的元素
*/
public synchronized E elementAt(int index) {
//如果索引值大于数组长度,抛出一个异常
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
//返回位于该索引的元素
return elementData(index);
}
/**
* 返回该集合中的第一个元素
* @return 该集合中的第一个元素
*/
public synchronized E firstElement() {
//如果集合为空,抛出一个异常
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(0);
}
/**
* 返回该集合中的最后一个元素
* @return 返回该集合中的最后一个元素
*/
public synchronized E lastElement() {
//如果集合为空,抛出一个异常
if (elementCount == 0) {
throw new NoSuchElementException();
}
return elementData(elementCount - 1);
}
/**
* 将某个对象赋予集合中的某个索引位置
* @param obj 赋予某个对象
* @param index 索引值
*/
public synchronized void setElementAt(E obj, int index) {
//如果索引值大于数组长度,抛出一个异常
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " +
elementCount);
}
//将obj赋给数组中的第index项
elementData[index] = obj;
}
/**
* 删除位于某个位置的元素
* @param index 该位置的索引值
*/
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) {
//arraycopy的含义是将elementData数组里从索引为index + 1的元素开始, 复制到数组elementData里的索引为index的位置, 复制的元素个数为j个.
//相当于用后两个代替了后三个,将位于index位置的元素删除
System.arraycopy(elementData, index + 1, elementData, index, j);
}
elementCount--;
//删除后,将最后一位置为null
elementData[elementCount] = null;
}
/**
* 在某个位置添加元素
* @param obj 需要添加的元素
* @param index 需要添加的位置
*/
public synchronized void insertElementAt(E obj, int index) {
modCount++;
if (index > elementCount) {
throw new ArrayIndexOutOfBoundsException(index
+ " > " + elementCount);
}
//将数组的长度扩大一
ensureCapacityHelper(elementCount + 1);
//和remove的原理类似,将位于index项后的拷贝到index+1位置,相当于在index位置元素复制一个元素
System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
//将obj赋予数组位于index的位置
elementData[index] = obj;
elementCount++;
}
/**
* 在元素的末尾添加一个元素
* @param obj 需要添加的元素
*/
public synchronized void addElement(E obj) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = obj;
}
/**
* 删除某个元素
* @param obj 需要删除的元素
* @return 删除成功返回true,删除失败返回fasle
*/
public synchronized boolean removeElement(Object obj) {
modCount++;
int i = indexOf(obj);
if (i >= 0) {
removeElementAt(i);
return true;
}
return false;
}
/**
* 删除所有元素
*/
public synchronized void removeAllElements() {
modCount++;
for (int i = 0; i < elementCount; i++) {
elementData[i] = null;
}
elementCount = 0;
}
/**
* 克隆一个新对象
* @return 返回的是克隆得到的对象
*/
@Override
public synchronized Object clone() {
try {
@SuppressWarnings("unchecked")
Vector<E> v = (Vector<E>) super.clone();
v.elementData = Arrays.copyOf(elementData, elementCount);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
/**
* 将该集合转化为数组
* @return 返回的是转化后的数组
*/
@Override
public synchronized Object[] toArray() {
return Arrays.copyOf(elementData, elementCount);
}
/**
* 将该集合转化为某种类型的数组
* @param a 需要转化的类型
* @param <T> 返回的数组类型
* @return 返回的数组
*/
@Override
@SuppressWarnings("unchecked")
public synchronized <T> T[] toArray(T[] a) {
if (a.length < elementCount) {
return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());
}
System.arraycopy(elementData, 0, a, 0, elementCount);
if (a.length > elementCount) {
a[elementCount] = null;
}
return a;
}
/**
* 获取位于某个索引的元素
* @param index 索引值
* @return 该索引值的元素
*/
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
/**
* 获取位于某个位置的元素
* @param index 该位置的索引
* @return 该位置的元素
*/
@Override
public synchronized E get(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index);
}
return elementData(index);
}
/**
* 将某个索引的位置设置为某个元素
* @param index 索引
* @param element 将该对象替代该索引位置的元素
* @return 返回的是被替代的元素
*/
@Override
public synchronized E set(int index, E element) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index);
}
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
/**
* 在集合的末尾添加一个元素
* @param e 需要添加的元素
* @return 添加成功返回true,添加失败返回false
*/
@Override
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
/**
* 将集合中的元素删除
* @param o 需要删除的元素
* @return 返回的是否删除成功
*/
@Override
public boolean remove(Object o) {
return removeElement(o);
}
/**
* 将钙元素添加到该集合某个索引对应的位置
* @param index 索引值
* @param element 需要添加的元素
*/
@Override
public void add(int index, E element) {
insertElementAt(element, index);
}
/**
* 删除位于某个索引位置的元素
* @param index 索引值
* @return 删除的元素
*/
@Override
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) {
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
}
elementData[--elementCount] = null;
return oldValue;
}
/**
* 删除集合中的所有元素
*/
@Override
public void clear() {
removeAllElements();
}
/**
* 该集合是否包含另一个集合中的所有元素
* @param c 另一个集合
* @return 包含返回true,不包含返回false
*/
@Override
public synchronized boolean containsAll(Collection<?> c) {
//调用的是AbstractCollection中实现的containsAll
return super.containsAll(c);
}
/**
* 将某个集合中的所有元素添加到该集合中
* @param c 需要添加的集合
* @return 返回的是是否添加成功
*/
@Override
public synchronized boolean addAll(Collection<? extends E> c) {
modCount++;
//大概思路就是讲该集合转换成数组,然后通过arraycopy方法来实现在原集合末尾将该集合元素新增到其中
Object[] a = c.toArray();
int numNew = a.length;
//首先需要对该集合进行扩容的操作
ensureCapacityHelper(elementCount + numNew);
//然后进行追加
System.arraycopy(a, 0, elementData, elementCount, numNew);
elementCount += numNew;
return numNew != 0;
}
/**
* 删除集合中包含另一个集合的所有元素
* @param c 需要删除的集合
* @return
*/
@Override
public synchronized boolean removeAll(Collection<?> c) {
//这里调用的是AbstractCollection中的实现
return super.removeAll(c);
}
/**
* 在此集合中仅保留包含在指定Collection中的元素(取交集)
* @param c 要在此集合中保留的元素的 collection
* @return 如果此集合由于调用而更改,返回true
*/
@Override
public synchronized boolean retainAll(Collection<?> c) {
//这里调用的是AbstractCollection中的实现
return super.retainAll(c);
}
/**
* 在指定位置将指定 Collection 中的所有元素插入到此集合中。
* 将当前位于该位置的元素(如果有)及所有后续元素右移(增大其索引值)。
* 新元素在集合中按照其由指定 collection 的迭代器所返回的顺序出现。
* @param index 要插入指定 collection 的第一个元素的索引
* @param c 要插入到此集合的元素
* @return 如果此向量由于调用而更改,则返回 true
*/
@Override
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) {
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
}
System.arraycopy(a, 0, elementData, index, numNew);
elementCount += numNew;
return numNew != 0;
}
/**
* 比较指定对象与此集合的相等性。当且仅当指定的对象也是一个 List,两个 List 大小相同,并且其中所有对应的元素对都 相等 时才返回 true。
* @param o
* @return
*/
@Override
public synchronized boolean equals(Object o) {
//其实这里调用的是AbstractList中的实现
return super.equals(o);
}
/**
* 返回此集合的哈希码值。
* @return 此集合的哈希码值
*/
@Override
public synchronized int hashCode() {
//其实这里调用的是AbstractList中的实现
return super.hashCode();
}
/**
* 返回此集合的字符串表示形式,其中包含每个元素的 String 表示形式。
* @return 此 collection 的字符串表示形式
*/
@Override
public synchronized String toString() {
//其实这里调用的是AbstractCollection中的实现
return super.toString();
}
/**
* 返回此 List 的部分视图,元素范围为从 fromIndex(包括)到 toIndex(不包括)
* @param fromIndex
* @param toIndex
* @return
*/
@Override
public synchronized List<E> subList(int fromIndex, int toIndex) {
//实际上还是调用的AbstractList的实现
return super.subList(fromIndex, toIndex);
//源码中这么写的,但是由于包的原因,在这个地方会报错,这里的作用是将该集合包装为一个线程安全的集合
//return Collections.synchronizedList(super.subList(fromIndex, toIndex),
// this);
}
/**
* 从此 List 中移除其索引位于 fromIndex(包括)与 toIndex(不包括)之间的所有元素
* @param fromIndex 要移除的第一个元素的索引
* @param toIndex 要移除的最后一个元素之后的索引
*/
@Override
protected synchronized void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = elementCount - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
int newElementCount = elementCount - (toIndex-fromIndex);
while (elementCount != newElementCount) {
elementData[--elementCount] = null;
}
}
/**
* 序列化读
* @param in 输入流读
* @throws IOException
* @throws ClassNotFoundException
* @throws StreamCorruptedException
*/
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException, StreamCorruptedException {
ObjectInputStream.GetField gfields = in.readFields();
int count = gfields.get("elementCount", 0);
Object[] data = (Object[])gfields.get("elementData", null);
if (count < 0 || data == null || count > data.length) {
throw new StreamCorruptedException("Inconsistent vector internals");
}
elementCount = count;
elementData = data.clone();
}
/**
* 序列化写
* @param s 输出流写
* @throws java.io.IOException
*/
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
final java.io.ObjectOutputStream.PutField fields = s.putFields();
final Object[] data;
synchronized (this) {
fields.put("capacityIncrement", capacityIncrement);
fields.put("elementCount", elementCount);
data = elementData.clone();
}
fields.put("elementData", data);
s.writeFields();
}
/**
* 获取某一索引位置开始的ListIterator实例
* @param index 该位置的索引值
* @return 以该位置为初始的ListIterator
*/
@Override
public synchronized ListIterator<E> listIterator(int index) {
if (index < 0 || index > elementCount) {
throw new IndexOutOfBoundsException("Index: "+index);
}
return new ListItr(index);
}
/**
* 获取首位开始的ListIterator实例
* @return 返回的是首位开始的ListIterator
*/
@Override
public synchronized ListIterator<E> listIterator() {
return new ListItr(0);
}
/**
* 获取该集合的Iterator实例
* @return 返回的是该集合的Iterator实例
*/
@Override
public synchronized Iterator<E> iterator() {
return new Itr();
}
/**
* 这里的实现和AbstractList中的实现并没有太大的区别,具体的可以参考AbstractList中的实现
*/
private class Itr implements Iterator<E> {
int cursor;
int lastRet = -1;
int expectedModCount = modCount;
@Override
public boolean hasNext() {
return cursor != elementCount;
}
@Override
public E next() {
//唯一不同的是这里的操作都会标记为同步的,确保了线程的安全性
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount) {
throw new NoSuchElementException();
}
cursor = i + 1;
return elementData(lastRet = i);
}
}
@Override
public void remove() {
if (lastRet == -1) {
throw new IllegalStateException();
}
synchronized (Vector.this) {
checkForComodification();
Vector.this.remove(lastRet);
expectedModCount = modCount;
}
cursor = lastRet;
lastRet = -1;
}
@Override
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
synchronized (Vector.this) {
final int size = elementCount;
int i = cursor;
if (i >= size) {
return;
}
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) Vector.this.elementData;
if (i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
action.accept(elementData[i++]);
}
cursor = i;
lastRet = i - 1;
checkForComodification();
}
}
final void checkForComodification() {
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
}
final class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
@Override
public boolean hasPrevious() {
return cursor != 0;
}
@Override
public int nextIndex() {
return cursor;
}
@Override
public int previousIndex() {
return cursor - 1;
}
@Override
public E previous() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor - 1;
if (i < 0) {
throw new NoSuchElementException();
}
cursor = i;
return elementData(lastRet = i);
}
}
@Override
public void set(E e) {
if (lastRet == -1) {
throw new IllegalStateException();
}
synchronized (Vector.this) {
checkForComodification();
Vector.this.set(lastRet, e);
}
}
@Override
public void add(E e) {
int i = cursor;
synchronized (Vector.this) {
checkForComodification();
Vector.this.add(i, e);
expectedModCount = modCount;
}
cursor = i + 1;
lastRet = -1;
}
}
/**
* 遍历集合,这里传入的是一个函数式接口,可以配合lambda表达式来使用
* 用法如下 c.forEach(cStr -> System.out.prinltn(cStr))
* @param action 所做的操作
*/
@Override
public synchronized void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
final int expectedModCount = modCount;
@SuppressWarnings("unchecked")
final E[] elementData = (E[]) this.elementData;
final int elementCount = this.elementCount;
for (int i=0; modCount == expectedModCount && i < elementCount; i++) {
action.accept(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
/**
* 这里传入的是同样是一个函数式接口,用于判断条件的过滤器,可以配合lambda表达式来使用,符合条件的会被删除
* @param filter 过滤条件
* @return
*/
@Override
@SuppressWarnings("unchecked")
public synchronized boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
int removeCount = 0;
final int size = elementCount;
final BitSet removeSet = new BitSet(size);
final int expectedModCount = modCount;
for (int i=0; modCount == expectedModCount && i < size; i++) {
@SuppressWarnings("unchecked")
final E element = (E) elementData[i];
if (filter.test(element)) {
removeSet.set(i);
removeCount++;
}
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
final int newSize = size - removeCount;
for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
elementData[j] = elementData[i];
}
for (int k=newSize; k < size; k++) {
elementData[k] = null;
}
elementCount = newSize;
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
return anyToRemove;
}
/**
* 对集合进行全部进行一元操作后替换原有集合,传入的是一个一元操作的函数式接口
* @param operator 一元操作
*/
@Override
@SuppressWarnings("unchecked")
public synchronized void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
final int expectedModCount = modCount;
final int size = elementCount;
for (int i=0; modCount == expectedModCount && i < size; i++) {
elementData[i] = operator.apply((E) elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
/**
* 根据指定的排序函数进行排序,传入的是一个函数式接口,可以配合lambda表达式使用
* @param c
*/
@SuppressWarnings("unchecked")
@Override
public synchronized void sort(Comparator<? super E> c) {
final int expectedModCount = modCount;
Arrays.sort((E[]) elementData, 0, elementCount, c);
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
modCount++;
}
/**
* Spliterator是一个可分割迭代器(splitable iterator),
* @return 返回的是一个VectorSpliterator的实例
*/
@Override
public Spliterator<E> spliterator() {
return new VectorSpliterator<>(this, null, 0, -1, 0);
}
static final class VectorSpliterator<E> implements Spliterator<E> {
private final Vector<E> list;
private Object[] array;
/**
*
*/
private int index;
/**
* 未使用的时候是-1,使用之后为上次迭代器越过的位置
*/
private int fence;
/**
* 当fence设置值的时候被初始化
*/
private int expectedModCount;
VectorSpliterator(Vector<E> list, Object[] array, int origin, int fence,
int expectedModCount) {
this.list = list;
this.array = array;
this.index = origin;
this.fence = fence;
this.expectedModCount = expectedModCount;
}
/**
* 首次使用的时候被初始化为-1,后面调用的时候获取的是fence的值。
* @return
*/
private int getFence() {
int hi;
if ((hi = fence) < 0) {
synchronized(list) {
array = list.elementData;
expectedModCount = list.modCount;
hi = fence = list.elementCount;
}
}
return hi;
}
/**
* 再次进行分割,分割的位置为中间(>>> 1)
* @return
*/
@Override
public Spliterator<E> trySplit() {
int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
return (lo >= mid) ? null :
new VectorSpliterator<E>(list, array, lo, index = mid,
expectedModCount);
}
/**
* 如果剩余元素存在,则执行给定的操作,并返回true; 否则返回false。
* @param action
* @return
*/
@Override
@SuppressWarnings("unchecked")
public boolean tryAdvance(Consumer<? super E> action) {
int i;
if (action == null) {
throw new NullPointerException();
}
if (getFence() > (i = index)) {
index = i + 1;
action.accept((E)array[i]);
if (list.modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
return true;
}
return false;
}
/**
* 遍历后对每项进行对应的操作
* @param action
*/
@Override
@SuppressWarnings("unchecked")
public void forEachRemaining(Consumer<? super E> action) {
int i, hi;
Vector<E> lst; Object[] a;
if
(action == null) {
throw new NullPointerException();
}
if ((lst = list) != null) {
if ((hi = fence) < 0) {
synchronized(lst) {
expectedModCount = lst.modCount;
a = array = lst.elementData;
hi = fence = lst.elementCount;
}
}
else {
a = array;
}
if (a != null && (i = index) >= 0 && (index = hi) <= a.length) {
while (i < hi) {
action.accept((E) a[i++]);
}
if (lst.modCount == expectedModCount) {
return;
}
}
}
throw new ConcurrentModificationException();
}
/**
* 提供剩余元素数量的估计
* @return 剩余元素数量的估计
*/
@Override
public long estimateSize() {
return (long) (getFence() - index);
}
/**
*返回此Spliterator及其元素的一组特征。
* @return
*/
@Override
public int characteristics() {
return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
}
}
}
以上的源码分析中,我们对于这个类已经有了一个充足的了解, Vector实际上是通过一个数组去保存数据的。当我们构造Vecotr时;若使用默认构造函数,则Vector的默认容量大小是10。 当Vector容器的容量不足以容纳全部元素时,Vector的容量会增加。若容量增加系数 >0,则将容量的值增加“容量增加系数”;否则,将容量大小增加一倍。
Vector的遍历方法从原理上来说有三种,而非网上所说的四种(网上把增强for循环当做了一个方法,实际上只是一个语法糖,它仍会被编译为迭代器循环)。
- 迭代器遍历
- 随机访问
Enumeration
遍历
Stack
简介
栈(Stack
)是Vector
的一个子类,它实现了一个标准的后进先出的栈。
结构图
源码
public class Stack<E> extends Vector<E> {
/**
* Stack的无参构造函数
*/
public Stack() {
}
/**
* 把项压入堆栈顶部
*/
public E push(E item) {
addElement(item);
return item;
}
/**
* 移除堆栈顶部的对象,并作为此函数的值返回该对象。
* @return 被移除的对象
*/
public synchronized E pop() {
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
/**
* 查看堆栈顶部的对象
* @return
*/
public synchronized E peek() {
int len = size();
if (len == 0) {
throw new EmptyStackException();
}
return elementAt(len - 1);
}
/**
* 测试堆栈是否为空
* @return
*/
public boolean empty() {
return size() == 0;
}
/**
* 返回对象在堆栈中的位置,以 1 为基数
* @param o 需要查找位置的对象
* @return
*/
public synchronized int search(Object o) {
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
/**
* 版本id
*/
private static final long serialVersionUID = 1224463164541339165L;
}
Stack
继承自Vector
,说明它也是通过数组实现的**,**而非链表。而且Vector
类具有的特性它都具有。
关于动态扩容的知识,由于Vector
我们用的比较少,只是在源码中进行了详解,而在下一节ArrayList
的讲解中,我们会对这一块儿单独进行讲解,毕竟在日常的开发中,ArrayList
是我们用到的最多的集合类之一,而它线程不安全的问题,我们可以通过其他的方式来解决,这样既保证了效率,又保证了安全性。
下节预告
重头戏ArrayList
来了,数据结构,源码解析,我们周五见~