java ArrayList類詳解及Vector類簡介
/**
* ArrayList詳解及Vector簡介
*/
public class TestArrayList2 {
? ?public static void main(String[] args) {
? ? ? ?/* ArrayList源碼
? ? ? ?public class ArrayList<E> extends AbstractList<E>
? ? ? ?implements List<E>, RandomAccess, Cloneable, java.io.Serializable
? ? ? ?//泛型類<E> 實(shí)現(xiàn)List<E>
? ? ? ?private static final int DEFAULT_CAPACITY = 10;
? ? ? ?//默認(rèn)容量10 當(dāng)?shù)谝淮翁砑釉貢r如果一次性添加數(shù)量小于等于10會將容器的容量capacity變?yōu)?0
? ? ? ?private static final Object[] EMPTY_ELEMENTDATA = {};
? ? ? ?//空_元素數(shù)據(jù)
? ? ? ?private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
? ? ? ?//默認(rèn)容量_空_元素數(shù)據(jù) 空數(shù)組 new ArrayList()無參時會將容器的數(shù)組設(shè)定為{}
? ? ? ?transient Object[] elementData;
? ? ? ?//elementData元素數(shù)據(jù) Object[]數(shù)組 用于存放容器中的元素
? ? ? ?private int size;
? ? ? ?//.size()返回的size 容器中元素的數(shù)量
? ? ? ?public ArrayList(int initialCapacity) {
? ? ? ? ? ?if (initialCapacity > 0) {
? ? ? ? ? ? ? ?this.elementData = new Object[initialCapacity];
? ? ? ? ? ?} else if (initialCapacity == 0) {
? ? ? ? ? ? ? ?this.elementData = EMPTY_ELEMENTDATA;
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?throw new IllegalArgumentException("Illegal Capacity: "+
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? initialCapacity);
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?//有參構(gòu)造器 initial最初的 ?設(shè)定容器初始大小size為initialCapacity
? ? ? ?//當(dāng)參數(shù)==0時將elementData賦值為EMPTY_ELEMENTDATA
? ? ? ?public ArrayList() {
? ? ? ? ? ?this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
? ? ? ?}
? ? ? ?//無參構(gòu)造器 將elementData賦值為DEFAULTCAPACITY_EMPTY_ELEMENTDATA
? ? ? ?public ArrayList(Collection<? extends E> c) {
? ? ? ? ? ?Object[] a = c.toArray();
? ? ? ? ? ?if ((size = a.length) != 0) {
? ? ? ? ? ? ? ?if (c.getClass() == ArrayList.class) {
? ? ? ? ? ? ? ? ? ?elementData = a;
? ? ? ? ? ? ? ?} else {
? ? ? ? ? ? ? ? ? ?elementData = Arrays.copyOf(a, size, Object[].class);
? ? ? ? ? ? ? ?}
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?elementData = EMPTY_ELEMENTDATA;
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?//將容器c傳參給構(gòu)造器 將this.size設(shè)為容器c的元素數(shù) 將this.elementData設(shè)為容器c的數(shù)組 如果c不是ArrayList類將數(shù)組轉(zhuǎn)換為Object[]再賦值給elementData
? ? ? ?public void trimToSize() {
? ? ? ? ? ?modCount++;
? ? ? ? ? ?if (size < elementData.length) {
? ? ? ? ? ? ? ?elementData = (size == 0)
? ? ? ? ? ? ? ? ?? EMPTY_ELEMENTDATA
? ? ? ? ? ? ? ? ?: Arrays.copyOf(elementData, size);
? ? ? ? ? ?}
? ? ? ?}
? ? ? ?//trim修剪 將elementData中的元素拷貝至新的數(shù)組[size] 修剪掉數(shù)組中null未使用的索引 將數(shù)組的長度改為存放的元素總數(shù)size
? ? ? ?private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
? ? ? ?//size最大值為int最大值-8
? ? ? ?public int size() {
? ? ? ? ? ?return size;
? ? ? ?}
? ? ? ?//.size()方法返回size值
? ? ? ?public boolean isEmpty() {
? ? ? ? ? ?return size == 0;
? ? ? ?}
? ? ? ?//當(dāng)size為0時判斷容器為空
? ? ? ?public int indexOf(Object o) {
? ? ? ? ? ?if (o == null) {
? ? ? ? ? ? ? ?for (int i = 0; i < size; i++)
? ? ? ? ? ? ? ? ? ?if (elementData[i]==null)
? ? ? ? ? ? ? ? ? ? ? ?return i;
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?for (int i = 0; i < size; i++)
? ? ? ? ? ? ? ? ? ?if (o.equals(elementData[i]))
? ? ? ? ? ? ? ? ? ? ? ?return i;
? ? ? ? ? ?}
? ? ? ? ? ?return -1;
? ? ? ?}
? ? ? ?//從前往后遍歷elementData 查找第一個和參數(shù)o相同的元素 如果參數(shù)是null則返回elementData中第一個null 不存在返回-1
? ? ? ?public boolean contains(Object o) {
? ? ? ? ? ?return indexOf(o) >= 0;
? ? ? ?}
? ? ? ?//indexOf()不返回-1即容器中存在和參數(shù)o相同的元素
? ? ? ?public int lastIndexOf(Object o) {
? ? ? ? ? ?if (o == null) {
? ? ? ? ? ? ? ?for (int i = size-1; i >= 0; i--)
? ? ? ? ? ? ? ? ? ?if (elementData[i]==null)
? ? ? ? ? ? ? ? ? ? ? ?return i;
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?for (int i = size-1; i >= 0; i--)
? ? ? ? ? ? ? ? ? ?if (o.equals(elementData[i]))
? ? ? ? ? ? ? ? ? ? ? ?return i;
? ? ? ? ? ?}
? ? ? ? ? ?return -1;
? ? ? ?}
? ? ? ?//for循環(huán)從末位size-1往前查找
? ? ? ?public Object[] toArray() {
? ? ? ? ? ?return Arrays.copyOf(elementData, size);
? ? ? ?}
? ? ? ?//elementData是容器的存放元素的數(shù)組 size是元素真實(shí)的總數(shù) 數(shù)組中元素是從index0往后順序存入的 當(dāng)數(shù)組沒有存滿時數(shù)組中后面的位為空
? ? ? ?//Arrays.copyOf()創(chuàng)建一個新的數(shù)組 大小為size容器的元素真實(shí)總數(shù) 將elementData從[0]-[size-1]即所有元素拷貝到新數(shù)組中返回 返回類型為Object[]不是泛型
? ? ? ?public <T> T[] toArray(T[] a) {
? ? ? ? ? ?if (a.length < size)
? ? ? ? ? ? ? ?return (T[]) Arrays.copyOf(elementData, size, a.getClass());
? ? ? ? ? ?System.arraycopy(elementData, 0, a, 0, size);
? ? ? ? ? ?if (a.length > size)
? ? ? ? ? ? ? ?a[size] = null;
? ? ? ? ? ?return a;
? ? ? ?}
? ? ? ?//將容器中的元素拷貝到和形參a一致的數(shù)組類型的數(shù)組中返回 如果a的長度小于size則返回一個新的數(shù)組T[size] 否則將元素拷貝到a中 從index0位開始 比size長時將[size]位設(shè)為null 返回a
? ? ? ?public E get(int index) {
? ? ? ? ? ?rangeCheck(index);
? ? ? ? ? ?return elementData(index);
? ? ? ?}
? ? ? ?//返回索引位的元素 先判斷index在不在size范圍內(nèi)
? ? ? ?E elementData(int index) {return (E) elementData[index];}
? ? ? ?public E set(int index, E element) {
? ? ? ? ? ?rangeCheck(index);
? ? ? ? ? ?E oldValue = elementData(index);
? ? ? ? ? ?elementData[index] = element;
? ? ? ? ? ?return oldValue;
? ? ? ?}
? ? ? ?//替換元素 返回被替換元素
? ? ? ?public boolean add(E e) {
? ? ? ? ? ?ensureCapacityInternal(size + 1);
? ? ? ? ? ?elementData[size++] = e;
? ? ? ? ? ?return true;
? ? ? ?}
? ? ? ?//添加元素 先確保ensure 容量 如果elementData數(shù)組的長度不足會進(jìn)行擴(kuò)容
? ? ? ?//將e賦值給[size]位 size++ size反映容器中元素的數(shù)量 每次增減元素size都會改變相應(yīng)的數(shù)量
? ? ? ?//add(E e)是增加一個元素的方法 所以將size+1傳參進(jìn)ensureCapacityInternal()方法中判斷是否需要擴(kuò)容
? ? ? ?private void ensureCapacityInternal(int minCapacity) {
? ? ? ? ? ?ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
? ? ? ?}
? ? ? ?//minCapacity為需要的容器空間 ? calculateCapacity(elementData, minCapacity)方法如下
? ? ? ?private static int calculateCapacity(Object[] elementData, int minCapacity) {
? ? ? ? ? ?if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
? ? ? ? ? ? ? ?return Math.max(DEFAULT_CAPACITY, minCapacity);
? ? ? ? ? ?}
? ? ? ? ? ?return minCapacity;
? ? ? ?}
? ? ? ?//calculate計算 如果容器由無參構(gòu)造器生成,在初始化后沒有添加元素即elementData依然等于默認(rèn)容量空{(diào)},將默認(rèn)容量10和需要的容器空間比較選最大值返回 即初次添加元素后容器的size最小為10
? ? ? ?//如果容器內(nèi)已存在元素則返回所需空間的值 ?返回值作為參數(shù)傳給ensureExplicitCapacity()方法如下
? ? ? ?private void ensureExplicitCapacity(int minCapacity) {
? ? ? ? ? ?modCount++;
? ? ? ? ? ?if (minCapacity - elementData.length > 0)
? ? ? ? ? ? ? ?grow(minCapacity);
? ? ? ?}
? ? ? ?//explicit明確的 ?modCount修改計數(shù) 如果所需空間比當(dāng)前elementData的長度大則需要擴(kuò)容grow 方法如下
? ? ? ?private void grow(int minCapacity) {
? ? ? ? ? ?int oldCapacity = elementData.length;
? ? ? ? ? ?int newCapacity = oldCapacity + (oldCapacity >> 1);
? ? ? ? ? ?if (newCapacity - minCapacity < 0)
? ? ? ? ? ? ? ?newCapacity = minCapacity;
? ? ? ? ? ?if (newCapacity - MAX_ARRAY_SIZE > 0)
? ? ? ? ? ? ? ?newCapacity = hugeCapacity(minCapacity);
? ? ? ? ? ?elementData = Arrays.copyOf(elementData, newCapacity);
? ? ? ?}
? ? ? ?//先預(yù)設(shè)將數(shù)組的長度變?yōu)?.5倍 如果滿足所需空間則擴(kuò)容1.5 如果不滿足則將空間擴(kuò)容至所需空間的大小 擴(kuò)容會生成新的數(shù)組并將原數(shù)組拷貝過來
? ? ? ?public void add(int index, E element) {
? ? ? ? ? ?rangeCheckForAdd(index);
? ? ? ? ? ?ensureCapacityInternal(size + 1);
? ? ? ? ? ?System.arraycopy(elementData, index, elementData, index + 1,
? ? ? ? ? ? ? ? ? ? ? ? ? ? size - index);
? ? ? ? ? ?elementData[index] = element;
? ? ? ? ? ?size++;
? ? ? ?}
? ? ? ?//和add(E)基本相同 將從index位開始的元素拷貝到index+1位開始的位置 長度size-index即后移元素的總數(shù) 拷貝后將新元素賦值給index位
? ? ? ?public E remove(int index) {
? ? ? ? ? ?rangeCheck(index);
? ? ? ? ? ?modCount++;
? ? ? ? ? ?E oldValue = elementData(index);
? ? ? ? ? ?int numMoved = size - index - 1;
? ? ? ? ? ?if (numMoved > 0)
? ? ? ? ? ? ? ?System.arraycopy(elementData, index+1, elementData, index,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? numMoved);
? ? ? ? ? ?elementData[--size] = null; // clear to let GC do its work
? ? ? ? ? ?return oldValue;
? ? ? ?}
? ? ? ?//將被刪除的元素返回 判斷index位后面還有元素則將后面元素從index+1位開始拷貝至index位開始 將--size即原最后一個元素位賦null size減小
? ? ? ?public boolean remove(Object o) {
? ? ? ? ? ?if (o == null) {
? ? ? ? ? ? ? ?for (int index = 0; index < size; index++)
? ? ? ? ? ? ? ? ? ?if (elementData[index] == null) {
? ? ? ? ? ? ? ? ? ? ? ?fastRemove(index);
? ? ? ? ? ? ? ? ? ? ? ?return true;
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ?} else {
? ? ? ? ? ? ? ?for (int index = 0; index < size; index++)
? ? ? ? ? ? ? ? ? ?if (o.equals(elementData[index])) {
? ? ? ? ? ? ? ? ? ? ? ?fastRemove(index);
? ? ? ? ? ? ? ? ? ? ? ?return true;
? ? ? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ? ?return false;
? ? ? ?}
? ? ? ?//for遍歷數(shù)組直到size位之前 當(dāng)匹配到第一個相同元素時刪除并返回true 所以只能刪除第一個 fastRemove()方法不返回boolean
? ? ? ?public void clear() {
? ? ? ? ? ?modCount++;
? ? ? ? ? ?for (int i = 0; i < size; i++)
? ? ? ? ? ? ? ?elementData[i] = null;
? ? ? ? ? ?size = 0;
? ? ? ?}
? ? ? ?//遍歷數(shù)組全設(shè)為null size設(shè)為0
? ? ? ?public boolean addAll(Collection<? extends E> c) {
? ? ? ? ? ?Object[] a = c.toArray();
? ? ? ? ? ?int numNew = a.length;
? ? ? ? ? ?ensureCapacityInternal(size + numNew); ?// Increments modCount
? ? ? ? ? ?System.arraycopy(a, 0, elementData, size, numNew);
? ? ? ? ? ?size += numNew;
? ? ? ? ? ?return numNew != 0;
? ? ? ?}
? ? ? ?//和add()類似 如果所需空間大于數(shù)組的長度會擴(kuò)容 拷貝原數(shù)組內(nèi)容至新的數(shù)組中 再將形參c的數(shù)組拷貝到size位開始的位置即this容器的末尾
? ? ? ?//返回值是判斷形參c容器是否為空
? ? ? ?public boolean addAll(int index, Collection<? extends E> c) {
? ? ? ? ? ?rangeCheckForAdd(index);
? ? ? ? ? ?Object[] a = c.toArray();
? ? ? ? ? ?int numNew = a.length;
? ? ? ? ? ?ensureCapacityInternal(size + numNew);
? ? ? ? ? ?int numMoved = size - index;
? ? ? ? ? ?if (numMoved > 0)
? ? ? ? ? ? ? ?System.arraycopy(elementData, index, elementData, index + numNew,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? numMoved);
? ? ? ? ? ?System.arraycopy(a, 0, elementData, index, numNew);
? ? ? ? ? ?size += numNew;
? ? ? ? ? ?return numNew != 0;
? ? ? ?}
? ? ? ?//多了一個步驟判斷index位及后面是否有元素 將index位及后面的元素拷貝到index+numNew開始的位置
? ? ? ?public boolean removeAll(Collection<?> c) {
? ? ? ? ? ?Objects.requireNonNull(c);
? ? ? ? ? ?return batchRemove(c, false);
? ? ? ?}
? ? ? ?//removeAll和retainAll都通過batchRemove()執(zhí)行
? ? ? ?public boolean retainAll(Collection<?> c) {
? ? ? ? ? ?Objects.requireNonNull(c);
? ? ? ? ? ?return batchRemove(c, true);
? ? ? ?}
? ? ? ?//Objects.requireNonNull()判斷c為null則拋異常 否則返回c ?batchRemove()方法如下
? ? ? ?private boolean batchRemove(Collection<?> c, boolean complement) {
? ? ? ? ? ?final Object[] elementData = this.elementData;
? ? ? ? ? ?int r = 0, w = 0;
? ? ? ? ? ?//r讀 w寫
? ? ? ? ? ?boolean modified = false;
? ? ? ? ? ?try {
? ? ? ? ? ? ? ?for (; r < size; r++)
? ? ? ? ? ? ? ? ? ?if (c.contains(elementData[r]) == complement)
? ? ? ? ? ? ? ? ? ?//遍歷判斷this中的元素是否存在于c中 ?complement補(bǔ)充/交集
? ? ? ? ? ? ? ? ? ?//如果取交集retainAll時complement為true 需要contains()為true 即當(dāng)前元素在c中存在(true)==取交集(true) 執(zhí)行拷貝
? ? ? ? ? ? ? ? ? ? ? ?elementData[w++] = elementData[r];
? ? ? ? ? ? ? ? ? ? ? ?//如果取差集removeAll complement為false 需要contains()為false即當(dāng)前元素在c中不存在 false==false 才執(zhí)行拷貝
? ? ? ? ? ?} finally {
? ? ? ? ? ? ? ?if (r != size) {
? ? ? ? ? ? ? ? ? ?System.arraycopy(elementData, r,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? elementData, w,
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? size - r);
? ? ? ? ? ? ? ? ? ?w += size - r;
? ? ? ? ? ? ? ? ? ?//如果執(zhí)行過程中出現(xiàn)異常導(dǎo)致沒有完成數(shù)組的遍歷 會將剩余的部分拷貝至已完成部分的末尾來結(jié)束方法
? ? ? ? ? ? ? ?}
? ? ? ? ? ? ? ?if (w != size) {
? ? ? ? ? ? ? ? ? ?// clear to let GC do its work 當(dāng)索引位賦null 原元素/對象不再被調(diào)用后會被垃圾回收GC
? ? ? ? ? ? ? ? ? ?for (int i = w; i < size; i++)
? ? ? ? ? ? ? ? ? ? ? ?elementData[i] = null;
? ? ? ? ? ? ? ? ? ?modCount += size - w;
? ? ? ? ? ? ? ? ? ?size = w;
? ? ? ? ? ? ? ? ? ?modified = true;
? ? ? ? ? ? ? ? ? ?//w即符合要求的元素數(shù) 將符合的元素順序放在數(shù)組的前面 將后面的位置全部賦null 完成交集或者差集
? ? ? ? ? ? ? ?}
? ? ? ? ? ?}
? ? ? ? ? ?return modified;
? ? ? ?}
? ? ? ? */
? ?}
}
/*
Vector為List接口的實(shí)現(xiàn)類 基礎(chǔ)用法和ArrayList相同 vector矢量
ArrayList線程不安全 效率高
Vector線程安全 效率低
類似StringBuilder和StringBuffer的區(qū)別
List<String> v = new Vector<>();同樣通過List接口引用
Vector<>()源碼:
protected Object[] elementData;同樣使用elementData數(shù)組存儲元素
protected int elementCount;用于表示元素總數(shù) 作用同size
public Vector() {this(10);}無參構(gòu)造器直接初始size為10
private void grow(int minCapacity) {
? ? ? ?// 擴(kuò)容
? ? ? ?int oldCapacity = elementData.length;
? ? ? ?int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? capacityIncrement : oldCapacity);
? ? ? ?//Vector容器的空間是2倍擴(kuò)容
? ? ? ?if (newCapacity - minCapacity < 0)
? ? ? ? ? ?newCapacity = minCapacity;
? ? ? ?if (newCapacity - MAX_ARRAY_SIZE > 0)
? ? ? ? ? ?newCapacity = hugeCapacity(minCapacity);
? ? ? ?elementData = Arrays.copyOf(elementData, newCapacity);
? ?}
*/