深入理解Vector
vector的基础数据结构 也是数组,但是这个是线程同步的,占用资源比arrayList多。
vector应该翻译成向量更为合适,他是线程安全的arrayList但是他提供的功能比arrayList更多,但是又线程同步的,占用资源比ArrayList多。
//设置初始化长度 以及数组长度不够 扩展长度的大小(arrayList是扩展1.5倍,vector可以设置扩展好多,如果不设置默认为扩展初始长度)
public Vector(int initialCapacity, int capacityIncrement) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
this.capacityIncrement = capacityIncrement;
}
//initialCapacity 数组初始化的长度
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
//默认初始化长度为10
public Vector() {
this(10);
}
//将集合c赋值到Vector
public Vector(Collection<? extends E> c) {
elementData = c.toArray();
elementCount = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, elementCount, Object[].class);
}
一共四个构造器他们的区别就是在初始化数组长度,扩展长度,以及初始赋值的问题。
public Enumeration<E> elements() {
return new Enumeration<E>() {
int count = 0;
public boolean hasMoreElements() {
return count < elementCount;
}
public E nextElement() {
synchronized (Vector.this) {
if (count < elementCount) {
return elementData(count++);
}
}
throw new NoSuchElementException("Vector Enumeration");
}
};
}
这个是老版的迭代器。以后都使用Iterator这个迭代器,Vector的迭代器都是用synchronized修饰,是线程同步的。
public synchronized Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
public boolean hasNext() {
// Racy but within spec, since modifications are checked
// within or after synchronization in next/previous
return cursor != elementCount;
}
public E next() {
synchronized (Vector.this) {
checkForComodification();
int i = cursor;
if (i >= elementCount)
throw new NoSuchElementException();
cursor = i + 1;
return elementData(lastRet = i);
}
}
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++]);
}
// update once at end of iteration to reduce heap write traffic
cursor = i;
lastRet = i - 1;
checkForComodification();
}
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
数组变长方法 这里的增长方法和ArrayList是一样的,唯一不一样的事这里的扩容是直接为原来的一倍,而ArrayList是原来的1.5倍。
//minCapacity 变长的最小长度
/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
//如果没有设置变长长度capacityIncrement 就将原来的长度相加长度扩展一倍
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
//新的长度(扩展后的长度)如果是小于设置的最小长度minCapacity 自然新长度就是这个最小长度,如果新长度已经大于最大数组长度 就去判断得到新的长度
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
//然后将数组扩展到新的长度。
elementData = Arrays.copyOf(elementData, newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
//返回当前的容量,arraylist没有这个方法。
public synchronized int capacity() {
return elementData.length;
}
indexOf(Object) indexOf(object,int)方法 一个参数的方法,他遍历的起始位置是0。所以这里使用的是for循环遍历,如果vector的值多了,最好还是使用两个参数的方法,这样能够使,遍历的内容稍微少一些。
public synchronized int indexOf(Object o, int index) {
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;
}
return -1;
}
lastIndexOf() 方法是倒起来遍历 其结构 什么的都是和indexOf()方法类似
public synchronized int lastIndexOf(Object o, int index) {
if (index >= elementCount)
throw new IndexOutOfBoundsException(index + " >= "+ elementCount);
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;
}
return -1;
}
get()方法 和elementAt()两个方法都是一样的,估计是elementAt是开始就有的 get是1.2以后才有的方法,应该是java后来对集合做了一个重新的定义。
public synchronized E elementAt(int index) {
if (index >= elementCount) {
throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
}
return elementData(index);
}
//@since 1.2
public synchronized E get(int index) {
if (index >= elementCount)
throw new ArrayIndexOutOfBoundsException(index);
return elementData(index);
}
1.8新加的方法 没有多少注释,他的用法也和arraylist的一样,只是都加了锁,线程安全
public synchronized void forEach(Consumer<? super E> action) {
//````
}
public synchronized boolean removeIf(Predicate<? super E> filter) {
//、、、
}
这里的retainAll 是在抽象类AbstractCollection中实现的。作用是移除不在集合c中的元素
public synchronized boolean retainAll(Collection<?> c) {
return super.retainAll(c);
}
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}