Java中的List
?? 轉載請注明原文地址:http://www.cnblogs.com/ygj0930/p/6538256.html
?? Java中常用的List子類主要有:ArrayList、LinkedList、Vector。
?? 一:ArrayList
?? ArrayList實現了List接口,實現了一系列的add()/get()/clear()/remove()等接口中的方法。其底層其實是一個數組,通過對數組上一系列操作的封裝來實現list的各種功能的。
package java.util;public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {// 序列版本號private static final long serialVersionUID = 8683452581122892189L;// 保存ArrayList中數據的數組private transient Object[] elementData;// ArrayList中實際數據的數量private int size;// ArrayList帶容量大小的構造函數。public ArrayList(int initialCapacity) {super();if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);// 新建一個數組this.elementData = new Object[initialCapacity];}// ArrayList構造函數。默認容量是10。public ArrayList() {this(10);}// 創建一個包含collection的ArrayListpublic ArrayList(Collection<? extends E> c) {elementData = c.toArray();size = elementData.length;// c.toArray might (incorrectly) not return Object[] (see 6260652)if (elementData.getClass() != Object[].class)elementData = Arrays.copyOf(elementData, size, Object[].class);}// 將當前容量值設為 =實際元素個數public void trimToSize() {modCount++;int oldCapacity = elementData.length;if (size < oldCapacity) {elementData = Arrays.copyOf(elementData, size);}}// 確定ArrarList的容量。// 若ArrayList的容量不足以容納當前的全部元素,設置 新的容量=“(原始容量x3)/2 + 1”public void ensureCapacity(int minCapacity) {// 將“修改統計數”+1modCount++;int oldCapacity = elementData.length;// 若當前容量不足以容納當前的元素個數,設置 新的容量=“(原始容量x3)/2 + 1”if (minCapacity > oldCapacity) {Object oldData[] = elementData;int newCapacity = (oldCapacity * 3)/2 + 1;if (newCapacity < minCapacity)newCapacity = minCapacity;elementData = Arrays.copyOf(elementData, newCapacity);}}// 添加元素epublic boolean add(E e) {// 確定ArrayList的容量大小ensureCapacity(size + 1); // Increments modCount!!// 添加e到ArrayList中elementData[size++] = e;return true;}// 返回ArrayList的實際大小public int size() {return size;}// 返回ArrayList是否包含Object(o)public boolean contains(Object o) {return indexOf(o) >= 0;}// 返回ArrayList是否為空public boolean isEmpty() {return 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;}// 反向查找,返回元素的索引值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;}// 反向查找(從數組末尾向開始查找),返回元素(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;}// 返回ArrayList的Object數組public Object[] toArray() {return Arrays.copyOf(elementData, size);}// 返回ArrayList的模板數組。所謂模板數組,即可以將T設為任意的數據類型public <T> T[] toArray(T[] a) {// 若數組a的大小 < ArrayList的元素個數;// 則新建一個T[]數組,數組大小是“ArrayList的元素個數”,并將“ArrayList”全部拷貝到新數組中if (a.length < size)return (T[]) Arrays.copyOf(elementData, size, a.getClass());// 若數組a的大小 >= ArrayList的元素個數;// 則將ArrayList的全部元素都拷貝到數組a中。System.arraycopy(elementData, 0, a, 0, size);if (a.length > size)a[size] = null;return a;}// 獲取index位置的元素值public E get(int index) {RangeCheck(index);return (E) elementData[index];}// 設置index位置的值為elementpublic E set(int index, E element) {RangeCheck(index);E oldValue = (E) elementData[index];elementData[index] = element;return oldValue;}// 將e添加到ArrayList中public boolean add(E e) {ensureCapacity(size + 1); // Increments modCount!!elementData[size++] = e;return true;}// 將e添加到ArrayList的指定位置public void add(int index, E element) {if (index > size || index < 0)throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);ensureCapacity(size+1); // Increments modCount!!System.arraycopy(elementData, index, elementData, index + 1,size - index);elementData[index] = element;size++;}// 刪除ArrayList指定位置的元素public E remove(int index) {RangeCheck(index);modCount++;E oldValue = (E) elementData[index];int numMoved = size - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--size] = null; // Let gc do its workreturn oldValue;}// 刪除ArrayList的指定元素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;}// 快速刪除第index個元素private void fastRemove(int index) {modCount++;int numMoved = size - index - 1;// 從"index+1"開始,用后面的元素替換前面的元素。if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);// 將最后一個元素設為nullelementData[--size] = null; // Let gc do its work }// 刪除元素public boolean remove(Object o) {if (o == null) {for (int index = 0; index < size; index++)if (elementData[index] == null) {fastRemove(index);return true;}} else {// 便利ArrayList,找到“元素o”,則刪除,并返回true。for (int index = 0; index < size; index++)if (o.equals(elementData[index])) {fastRemove(index);return true;}}return false;}// 清空ArrayList,將全部的元素設為nullpublic void clear() {modCount++;for (int i = 0; i < size; i++)elementData[i] = null;size = 0;}// 將集合c追加到ArrayList中public boolean addAll(Collection<? extends E> c) {Object[] a = c.toArray();int numNew = a.length;ensureCapacity(size + numNew); // Increments modCountSystem.arraycopy(a, 0, elementData, size, numNew);size += numNew;return numNew != 0;}// 從index位置開始,將集合c添加到ArrayListpublic boolean addAll(int index, Collection<? extends E> c) {if (index > size || index < 0)throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);Object[] a = c.toArray();int numNew = a.length;ensureCapacity(size + numNew); // Increments modCountint 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;}// 刪除fromIndex到toIndex之間的全部元素。protected void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = size - toIndex;System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);// Let gc do its workint newSize = size - (toIndex-fromIndex);while (size != newSize)elementData[--size] = null;}private void RangeCheck(int index) {if (index >= size)throw new IndexOutOfBoundsException("Index: "+index+", Size: "+size);}// 克隆函數public Object clone() {try {ArrayList<E> v = (ArrayList<E>) super.clone();// 將當前ArrayList的全部元素拷貝到v中v.elementData = Arrays.copyOf(elementData, size);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError();}}// java.io.Serializable的寫入函數// 將ArrayList的“容量,所有的元素值”都寫入到輸出流中private void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException{// Write out element count, and any hidden stuffint expectedModCount = modCount;s.defaultWriteObject();// 寫入“數組的容量” s.writeInt(elementData.length);// 寫入“數組的每一個元素”for (int i=0; i<size; i++)s.writeObject(elementData[i]);if (modCount != expectedModCount) {throw new ConcurrentModificationException();}}// java.io.Serializable的讀取函數:根據寫入方式讀出// 先將ArrayList的“容量”讀出,然后將“所有的元素值”讀出private void readObject(java.io.ObjectInputStream s)throws java.io.IOException, ClassNotFoundException {// Read in size, and any hidden stuff s.defaultReadObject();// 從輸入流中讀取ArrayList的“容量”int arrayLength = s.readInt();Object[] a = elementData = new Object[arrayLength];// 從輸入流中將“所有的元素值”讀出for (int i=0; i<size; i++)a[i] = s.readObject();} }?????? 1:ArrayList 實際上是通過一個數組去保存數據的。當我們構造ArrayList時;若使用默認構造函數,則ArrayList的默認容量大小是10。
????? 2:當ArrayList容量不足以容納全部元素時,ArrayList擴容:新的容量=“(原始容量x3)/2 + 1”。創建新容量大小的數組并把原數組內容復制過去。
????? 3:ArrayList的add()/get()/remove()等操作都是對底層的數組進行操作而已。
?
?? 二:LinkedList
??? LinkedList通過另一種方式實現List接口,不僅如此,它還實現了 Queue、Deque接口,使得LinkedList可以作為 棧、隊列、雙端隊列來使用。
??? LinkedList底層是一個 雙向鏈表。其對于 List、Queue、Deque接口中的方法都是通過封裝在鏈表上的操作來實現的。??
?
?
?? 三:Vector
?? Vector也是在底層通過一個數組來保存數據,通過底層數組的一系列操作來實現List接口的。
??
package java.util; public class Vector<E>extends AbstractList<E>implements List<E>, RandomAccess, Cloneable, java.io.Serializable {// 保存Vector中數據的數組protected Object[] elementData;// 實際數據的數量protected int elementCount;// 容量增長系數protected int capacityIncrement;// Vector的序列版本號private static final long serialVersionUID = -2767605614048989439L;// Vector構造函數。默認容量是10。public Vector() {this(10);}// 指定Vector容量大小的構造函數public Vector(int initialCapacity) {this(initialCapacity, 0);}// 指定Vector"容量大小"和"增長系數"的構造函數public Vector(int initialCapacity, int capacityIncrement) {super();if (initialCapacity < 0)throw new IllegalArgumentException("Illegal Capacity: "+initialCapacity);// 新建一個數組,數組容量是initialCapacitythis.elementData = new Object[initialCapacity];// 設置容量增長系數this.capacityIncrement = capacityIncrement;}// 指定集合的Vector構造函數。public Vector(Collection<? extends E> c) {// 獲取“集合(c)”的數組,并將其賦值給elementDataelementData = 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);}// 將數組Vector的全部元素都拷貝到數組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);}}// 確認“Vector容量”的幫助函數private void ensureCapacityHelper(int minCapacity) {int oldCapacity = elementData.length;// 當Vector的容量不足以容納當前的全部元素,增加容量大小。// 若 容量增量系數>0(即capacityIncrement>0),則將容量增大當capacityIncrement// 否則,將容量增大一倍。if (minCapacity > oldCapacity) {Object[] oldData = elementData;int newCapacity = (capacityIncrement > 0) ?(oldCapacity + capacityIncrement) : (oldCapacity * 2);if (newCapacity < minCapacity) {newCapacity = minCapacity;}elementData = Arrays.copyOf(elementData, newCapacity);}}// 確定Vector的容量。public synchronized void ensureCapacity(int minCapacity) {// 將Vector的改變統計數+1modCount++;ensureCapacityHelper(minCapacity);}// 設置容量值為 newSizepublic synchronized void setSize(int newSize) {modCount++;if (newSize > elementCount) {// 若 "newSize 大于 Vector容量",則調整Vector的大小。 ensureCapacityHelper(newSize);} else {// 若 "newSize 小于/等于 Vector容量",則將newSize位置開始的元素都設置為nullfor (int i = newSize ; i < elementCount ; i++) {elementData[i] = null;}}elementCount = newSize;}// 返回“Vector的總的容量”public synchronized int capacity() {return elementData.length;}// 返回“Vector的實際大小”,即Vector中元素個數public synchronized int size() {return elementCount;}// 判斷Vector是否為空public synchronized boolean isEmpty() {return elementCount == 0;}// 返回“Vector中全部元素對應的Enumeration”public Enumeration<E> elements() {// 通過匿名類實現Enumerationreturn new Enumeration<E>() {int count = 0;// 是否存在下一個元素public boolean hasMoreElements() {return count < elementCount;}// 獲取下一個元素public E nextElement() {synchronized (Vector.this) {if (count < elementCount) {return (E)elementData[count++];}}throw new NoSuchElementException("Vector Enumeration");}};}// 返回Vector中是否包含對象(o)public boolean contains(Object o) {return indexOf(o, 0) >= 0;}// 從index位置開始向后查找元素(o)。// 若找到,則返回元素的索引值;否則,返回-1public synchronized int indexOf(Object o, int index) {if (o == null) {// 若查找元素為null,則正向找出null元素,并返回它對應的序號for (int i = index ; i < elementCount ; i++)if (elementData[i]==null)return i;} else {// 若查找元素不為null,則正向找出該元素,并返回它對應的序號for (int i = index ; i < elementCount ; i++)if (o.equals(elementData[i]))return i;}return -1;}// 查找并返回元素(o)在Vector中的索引值public int indexOf(Object o) {return indexOf(o, 0);}// 從后向前查找元素(o)。并返回元素的索引public synchronized int lastIndexOf(Object o) {return lastIndexOf(o, elementCount-1);}// 從后向前查找元素(o)。開始位置是從前向后的第index個數;// 若找到,則返回元素的“索引值”;否則,返回-1。public synchronized int lastIndexOf(Object o, int index) {if (index >= elementCount)throw new IndexOutOfBoundsException(index + " >= "+ elementCount);if (o == null) {// 若查找元素為null,則反向找出null元素,并返回它對應的序號for (int i = index; i >= 0; i--)if (elementData[i]==null)return i;} else {// 若查找元素不為null,則反向找出該元素,并返回它對應的序號for (int i = index; i >= 0; i--)if (o.equals(elementData[i]))return i;}return -1;}// 返回Vector中index位置的元素。// 若index月結,則拋出異常public synchronized E elementAt(int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);}return (E)elementData[index];}// 獲取Vector中的第一個元素。// 若失敗,則拋出異常!public synchronized E firstElement() {if (elementCount == 0) {throw new NoSuchElementException();}return (E)elementData[0];}// 獲取Vector中的最后一個元素。// 若失敗,則拋出異常!public synchronized E lastElement() {if (elementCount == 0) {throw new NoSuchElementException();}return (E)elementData[elementCount - 1];}// 設置index位置的元素值為objpublic synchronized void setElementAt(E obj, int index) {if (index >= elementCount) {throw new ArrayIndexOutOfBoundsException(index + " >= " +elementCount);}elementData[index] = obj;}// 刪除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) {System.arraycopy(elementData, index + 1, elementData, index, j);}elementCount--;elementData[elementCount] = null; /* to let gc do its work */}// 在index位置處插入元素(obj)public synchronized void insertElementAt(E obj, int index) {modCount++;if (index > elementCount) {throw new ArrayIndexOutOfBoundsException(index+ " > " + elementCount);}ensureCapacityHelper(elementCount + 1);System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);elementData[index] = obj;elementCount++;}// 將“元素obj”添加到Vector末尾public synchronized void addElement(E obj) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = obj;}// 在Vector中查找并刪除元素obj。// 成功的話,返回true;否則,返回false。public synchronized boolean removeElement(Object obj) {modCount++;int i = indexOf(obj);if (i >= 0) {removeElementAt(i);return true;}return false;}// 刪除Vector中的全部元素public synchronized void removeAllElements() {modCount++;// 將Vector中的全部元素設為nullfor (int i = 0; i < elementCount; i++)elementData[i] = null;elementCount = 0;}// 克隆函數public synchronized Object clone() {try {Vector<E> v = (Vector<E>) super.clone();// 將當前Vector的全部元素拷貝到v中v.elementData = Arrays.copyOf(elementData, elementCount);v.modCount = 0;return v;} catch (CloneNotSupportedException e) {// this shouldn't happen, since we are Cloneablethrow new InternalError();}}// 返回Object數組public synchronized Object[] toArray() {return Arrays.copyOf(elementData, elementCount);}// 返回Vector的模板數組。所謂模板數組,即可以將T設為任意的數據類型public synchronized <T> T[] toArray(T[] a) {// 若數組a的大小 < Vector的元素個數;// 則新建一個T[]數組,數組大小是“Vector的元素個數”,并將“Vector”全部拷貝到新數組中if (a.length < elementCount)return (T[]) Arrays.copyOf(elementData, elementCount, a.getClass());// 若數組a的大小 >= Vector的元素個數;// 則將Vector的全部元素都拷貝到數組a中。System.arraycopy(elementData, 0, a, 0, elementCount);if (a.length > elementCount)a[elementCount] = null;return a;}// 獲取index位置的元素public synchronized E get(int index) {if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);return (E)elementData[index];}// 設置index位置的值為element。并返回index位置的原始值public synchronized E set(int index, E element) {if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);Object oldValue = elementData[index];elementData[index] = element;return (E)oldValue;}// 將“元素e”添加到Vector最后。public synchronized boolean add(E e) {modCount++;ensureCapacityHelper(elementCount + 1);elementData[elementCount++] = e;return true;}// 刪除Vector中的元素opublic boolean remove(Object o) {return removeElement(o);}// 在index位置添加元素elementpublic void add(int index, E element) {insertElementAt(element, index);}// 刪除index位置的元素,并返回index位置的原始值public synchronized E remove(int index) {modCount++;if (index >= elementCount)throw new ArrayIndexOutOfBoundsException(index);Object oldValue = elementData[index];int numMoved = elementCount - index - 1;if (numMoved > 0)System.arraycopy(elementData, index+1, elementData, index,numMoved);elementData[--elementCount] = null; // Let gc do its workreturn (E)oldValue;}// 清空Vectorpublic void clear() {removeAllElements();}// 返回Vector是否包含集合cpublic synchronized boolean containsAll(Collection<?> c) {return super.containsAll(c);}// 將集合c添加到Vector中public synchronized boolean addAll(Collection<? extends E> c) {modCount++;Object[] a = c.toArray();int numNew = a.length;ensureCapacityHelper(elementCount + numNew);// 將集合c的全部元素拷貝到數組elementData中System.arraycopy(a, 0, elementData, elementCount, numNew);elementCount += numNew;return numNew != 0;}// 刪除集合c的全部元素public synchronized boolean removeAll(Collection<?> c) {return super.removeAll(c);}// 刪除“非集合c中的元素”public synchronized boolean retainAll(Collection<?> c) {return super.retainAll(c);}// 從index位置開始,將集合c添加到Vector中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;}// 返回兩個對象是否相等public synchronized boolean equals(Object o) {return super.equals(o);}// 計算哈希值public synchronized int hashCode() {return super.hashCode();}// 調用父類的toString()public synchronized String toString() {return super.toString();}// 獲取Vector中fromIndex(包括)到toIndex(不包括)的子集public synchronized List<E> subList(int fromIndex, int toIndex) {return Collections.synchronizedList(super.subList(fromIndex, toIndex), this);}// 刪除Vector中fromIndex到toIndex的元素protected synchronized void removeRange(int fromIndex, int toIndex) {modCount++;int numMoved = elementCount - toIndex;System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);// Let gc do its workint newElementCount = elementCount - (toIndex-fromIndex);while (elementCount != newElementCount)elementData[--elementCount] = null;}// java.io.Serializable的寫入函數private synchronized void writeObject(java.io.ObjectOutputStream s)throws java.io.IOException {s.defaultWriteObject();} }??? 同ArrayList一樣,Vector底層數組容量不足時會擴容,然后把原有內容復制過去。
?
??? 四:三者比較
??? 1:訪問:ArrayList和Vector都實現了RandomAccess接口,提供了隨機訪問功能,查詢O(1);LinkedList是鏈表,查詢O(n);
??? 2:增刪:ArrayList和Vector底層是數組,增刪容易引起大量的內存操作,效率較慢;LinkedList是鏈表實現,增加和刪除較快;
??? 3:線程安全性:Vector是線程安全的,觀察上面源碼可以發現,大部分的方法都用了syncrhoized關鍵字修飾。所以,如果是單線程下使用,可以用Arrayist,如果是多線程操作的list,則可以用vector來保證線程安全。
??? 4:ArrayList每次擴容增加50%,Vector擴容增加一倍。
?
總結
以上是生活随笔為你收集整理的Java中的List的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux中网络通信中 使用的结构体
- 下一篇: Mybatis笔记一:java.lang