在java提高篇(二一)—–ArrayList、java提高篇(二二)—LinkedList,詳細解說了ArrayList、linkedList的原理與實作過程,對於List介面這裡也介紹一個它的實作類Vector ,Vector 類別可以實現可增長的物件數組。
Vector可實現可成長的物件陣列。與陣列一樣,它包含可以使用整數索引進行存取的元件。不過,Vector的大小是可以增加或減少的,以便適應建立Vector後進行新增或刪除操作。
Vector實現List接口,繼承AbstractList類,所以我們可以將其看做隊列,支援相關的新增、刪除、修改、遍歷等功能。
Vector實現RandmoAccess介面,即提供了隨機存取功能,並提供快速存取功能。在Vector我們可以直接存取元素。
Vector 實現了Cloneable介面,並支援clone()方法,可以被複製。
public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
Vector
在成員變數方面,Vector提供了elementData , elementCount,而 capacityIncrement三個成員變數。其中
elementData :"Object[]類型的陣列",它保存了Vector中的元素。依照Vector的設計elementData為一個動態數組,可以隨著元素的增加而動態的增長,其具體的增加方式後面提到(ensureCapacity方法)。如果在初始化Vector時沒有指定容器大小,則使用預設大小為10.
elementCount:Vector 物件中的有效元件數。
capacityIncrement:向量的大小大於其容量時,容量自動增加的量。如果在建立Vector時,指定了capacityIncrement的大小;則,每次當Vector中動態陣列容量增加時>,增加的大小都是capacityIncrement。如果容量的增量小於等於零,則每次需要增加容量時,向量的容量將增加一倍。
同時Vector是線程安全的! 二、原始碼解析
對於原始碼的解析,LZ在這裡只就增加兩個方法(加值)進行解釋。
add(E e):將指定元素加入此向量的結尾。
/** * 构造一个空向量,使其内部数据数组的大小为 10,其标准容量增量为零。 */ public Vector() { this(10); } /** * 构造一个包含指定 collection 中的元素的向量,这些元素按其 collection 的迭代器返回元素的顺序排列。 */ 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 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; }
這個方法相對而言比較簡單,具體過程就是先確認容器的大小,看是否需要進行擴充元素的此方法。
public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); //确认容器大小,如果操作容量则扩容操作 elementData[elementCount++] = e; //将e元素添加至末尾 return true; }
擴充至capacityIncrement 。當然這個容量的最大範圍為Integer.MAX_VALUE即,2^32 - 1,所以Vector並不是可以無限擴充的。
2.2、remove(Object o)
private void ensureCapacityHelper(int minCapacity) {
//如果
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* 进行扩容操作
* 如果此向量的当前容量小于minCapacity,则通过将其内部数组替换为一个较大的数组俩增加其容量。
* 新数据数组的大小姜维原来的大小 + capacityIncrement,
* 除非 capacityIncrement 的值小于等于零,在后一种情况下,新的容量将为原来容量的两倍,不过,如果此大小仍然小于 minCapacity,则新容量将为 minCapacity。
*/
private void grow(int minCapacity) {
int oldCapacity = elementData.length; //当前容器大小
/*
* 新容器大小
* 若容量增量系数(capacityIncrement) > 0,则将容器大小增加到capacityIncrement
* 否则将容量增加一倍
*/
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
/**
* 判断是否超出最大范围
* MAX_ARRAY_SIZE:private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
*/
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0)
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
}
因为Vector底层是使用数组实现的,所以它的操作都是对数组进行操作,只不过其是可以随着元素的增加而动态的改变容量大小,其实现方法是是使用Arrays.copyOf方法将旧数据拷贝到一个新的大容量数组中。Vector的整个内部实现都比较简单,这里就不在重述了。
Vector支持4种遍历方式。
因为Vector实现了RandmoAccess接口,可以通过下标来进行随机访问。
for(int i = 0 ; i < vec.size() ; i++){ value = vec.get(i); }
Iterator it = vec.iterator(); while(it.hasNext()){ value = it.next(); //do something }
for(Integer value:vec){ //do something }
Vector vec = new Vector<>(); Enumeration enu = vec.elements(); while (enu.hasMoreElements()) { value = (Integer)enu.nextElement(); }
——————————————————————————————————————————————————————————————————————————
以上就是java提高篇(二九)-----Vector的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!