Java基礎之List集合(包含JUC)學習程序(一)
Java中重要的集合包主要有Collection和map 複習collectioon,主要是List,Queue和Set
List
首先要知道List是一個介面,繼承自collection 其中定義了是元素有序並且可以重複的集合,被稱為序列,並且List允許存放null 因為有序,所以List是可以精確的控制元素的插入位置或刪除某個位置元素 注意List(如java陣列)下標index從0開始計數. 現在看一下list中都有哪些常用方法 (1)查詢操作
//list中元素個數 int size(); //非空查詢 boolean isEmpty(); //是否包含某物件o boolean contains(Object o); //迭代器 Iterator<E> iterator(); //返回一個包含list中所有元素的陣列(元素順序和list中一致); //執行時返回型別和引數陣列一致 Object[] toArray();
(2)修改操作
//插入到List表尾 boolean add(E e); //刪除list中首次出現的指定值(如果存在),如果不存在,則不進行任何操作. boolean remove(Object o); //移除list中的所有元素. void clear(); //sort採用的是歸併排序 default void sort(Comparator<? super E> c) { //獲取當前list中所有物件 Object[] a = this.toArray(); //根據比較器c對a排序 Arrays.sort(a, (Comparator) c); //利用迭代器將陣列中的元素型別進行強制轉型,到原來list中的型別 ListIterator<E> i = this.listIterator(); for (Object e : a) { i.next(); i.set((E) e); } } //equals方法 /** * 比較傳入物件o和當前list的等價性. * 相等條件: * 1.o型別為list * 2.二者size大小一樣 * 3.list中包含的元素順序一致. */ boolean equals(Object o);
查詢操作
//查詢元素首次在list中出現的位置,不存在返回-1
int indexOf(Object o);
//查詢元素最後一次在list中出現的位置,不存在返回-1
int lastIndexOf(Object o);
//返回子集
List<E> subList(int fromIndex, int toIndex);
List的基本的實現類有以下四個 ArrayList LinkedList Vector Stack
ArrayList是陣列實現的佇列,它是一個動態陣列;它不是執行緒安全的,只適用於單執行緒。 LinkedList是雙向連結串列實現的雙端佇列;它不是執行緒安全的,只適用於單執行緒。 Vector是陣列實現的向量佇列,它也一個動態陣列;不過和ArrayList不同的是,Vector是執行緒安全的,它支援併發。 Stack是Vector實現的棧;和Vector一樣,它也是執行緒安全的
並且在JUC中對List還有進一步的實現類 CopyOnWriteArrayList 它相當於執行緒安全的ArrayList,它實現了List介面。CopyOnWriteArrayList是支援高併發的,後面會介紹。
一一來介紹
ArrayList
ArrayList是陣列實現的,即動態陣列,可以動態的增加和減少元素,他實現了ICollection和IList介面,可以靈活的設定陣列的大小所有優勢在於遍歷查詢操作快,缺點在於插入刪除會比較慢。 相比較陣列而言,在1.8中,如果只是new ArrayList() ,容量是0,當第一次通過add(E e)時,才擴充為10。之後每次擴容就會以當前容量兩倍擴容,這是比較影響效率的,所以需要大容量的時候,在一開始定義一個合適的ArrayList的大小是有必要的。 其次,對於值型別來說,往ArrayList裡面新增和修改元素,都會引起裝箱和拆箱的操作,頻繁的操作也可能會影響一部分效率 原始碼如下
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
private static final long serialVersionUID = 8683452581122892189L;
//預設的初始容量為10
private static final int DEFAULT_CAPACITY = 10;
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;
// ArrayList中實際資料的數量
private int size;
public ArrayList(int initialCapacity) //帶初始容量大小的建構函式
{
if (initialCapacity > 0) //初始容量大於0,例項化陣列
{
this.elementData = new Object[initialCapacity];
}
else if (initialCapacity == 0) //初始化等於0,將空陣列賦給elementData
{
this.elementData = EMPTY_ELEMENTDATA;
}
else //初始容量小於,拋異常
{
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);
}
}
public ArrayList() //無參建構函式,預設容量為10
{
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
public ArrayList(Collection<? extends E> c) //建立一個包含collection的ArrayList
{
elementData = c.toArray(); //返回包含c所有元素的陣列
if ((size = elementData.length) != 0)
{
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);//複製指定陣列,使elementData具有指定長度
}
else
{
//c中沒有元素
this.elementData = EMPTY_ELEMENTDATA;
}
}
//將當前容量值設為當前實際元素大小
public void trimToSize()
{
modCount++;
if (size < elementData.length)
{
elementData = (size == 0)? EMPTY_ELEMENTDATA:Arrays.copyOf(elementData, size);
}
}
//將集合的capacit增加minCapacity
public void ensureCapacity(int minCapacity)
{
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)?0:DEFAULT_CAPACITY;
if (minCapacity > minExpand)
{
ensureExplicitCapacity(minCapacity);
}
}
private void ensureCapacityInternal(int minCapacity)
{
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
{
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity)
{
modCount++;
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
private void grow(int minCapacity)
{
int oldCapacity = elementData.length;
//注意此處擴充capacity的方式是將其向右一位再加上原來的數,實際上是擴充了1.5倍
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);
}
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 int size()
{
return size;
}
//判斷ArrayList是否為空
public boolean isEmpty() {
return size == 0;
}
//判斷ArrayList中是否包含Object(o)
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
//正向查詢,返回ArrayList中元素Object(o)的索引位置
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;
}
//逆向查詢,返回返回ArrayList中元素Object(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例項的淺拷貝。
public Object clone()
{
try
{
ArrayList<?> v = (ArrayList<?>) super.clone();
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
}
catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError(e);
}
}
//返回一個包含ArrayList中所有元素的陣列
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
@SuppressWarnings("unchecked")
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;
}
@SuppressWarnings("unchecked")
E elementData(int index) {
return (E) elementData[index];
}
//返回至指定索引的值
public E get(int index)
{
rangeCheck(index); //檢查給定的索引值是否越界
return 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;
}
// 將element新增到ArrayList的指定位置
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1);
//從指定源陣列中複製一個數組,複製從指定的位置開始,到目標陣列的指定位置結束。
//arraycopy(被複制的陣列, 從第幾個元素開始複製, 要複製到的陣列, 從第幾個元素開始貼上, 一共需要複製的元素個數)
//即在陣列elementData從index位置開始,複製到index+1位置,共複製size-index個元素
System.arraycopy(elementData, index, elementData, index + 1,size - index);
elementData[index] = element;
size++;
}
//刪除ArrayList指定位置的元素
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; //將原陣列最後一個位置置為null
return 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;
}
//快速刪除指定位置的元素
private void fastRemove(int index)
{
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index, numMoved);
elementData[--size] = null;
}
//清空ArrayList,將全部的元素設為null
public void clear()
{
modCount++;
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
//按照c的迭代器所返回的元素順序,將c中的所有元素新增到此列表的尾部
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;
}
//從指定位置index開始,將指定c中的所有元素插入到此列表中
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
//先將ArrayList中從index開始的numMoved個元素移動到起始位置為index+numNew的後面去
System.arraycopy(elementData, index, elementData, index + numNew, numMoved);
//再將c中的numNew個元素複製到起始位置為index的儲存空間中去
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
//刪除fromIndex到toIndex之間的全部元素
protected void removeRange(int fromIndex, int toIndex)
{
modCount++;
//numMoved為刪除索引後面的元素個數
int numMoved = size - toIndex;
//將刪除索引後面的元素複製到以fromIndex為起始位置的儲存空間中去
System.arraycopy(elementData, toIndex, elementData, fromIndex,numMoved);
int newSize = size - (toIndex-fromIndex);
//將ArrayList後面(toIndex-fromIndex)個元素置為null
for (int i = newSize; i < size; i++)
{
elementData[i] = null;
}
size = newSize;
}
//檢查索引是否越界
private void rangeCheck(int index)
{
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void rangeCheckForAdd(int index)
{
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
//刪除ArrayList中包含在c中的元素
public boolean removeAll(Collection<?> c)
{
Objects.requireNonNull(c);
return batchRemove(c, false);
}
//刪除ArrayList中除包含在c中的元素,和removeAll相反
public boolean retainAll(Collection<?> c)
{
Objects.requireNonNull(c); //檢查指定物件是否為空
return batchRemove(c, true);
}
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try
{
for (; r < size; r++)
if (c.contains(elementData[r]) == complement) //判斷c中是否有elementData[r]元素
elementData[w++] = elementData[r];
}
finally
{
if (r != size)
{
System.arraycopy(elementData, r, elementData, w, size - r);
w += size - r;
}
if (w != size)
{
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
//將ArrayList的“容量,所有的元素值”都寫入到輸出流中
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException
{
int expectedModCount = modCount;
s.defaultWriteObject();
//寫入陣列大小
s.writeInt(size);
//寫入所有陣列的元素
for (int i=0; i<size; i++) {
s.writeObject(elementData[i]);
}
if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}
}
//先將ArrayList的“大小”讀出,然後將“所有的元素值”讀出
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
elementData = EMPTY_ELEMENTDATA;
s.defaultReadObject();
s.readInt(); // ignored
if (size > 0) {
// be like clone(), allocate array based upon size not capacity
ensureCapacityInternal(size);
Object[] a = elementData;
// Read in all elements in the proper order.
for (int i=0; i<size; i++) {
a[i] = s.readObject();
}
}
}
LinkedList
LinkedList特性 LinkedList 是一個繼承於AbstractSequentialList的雙向連結串列。它也可以被當作堆疊、佇列或雙端佇列進行操作。 LinkedList 實現 List 介面,能對它進行佇列操作。 LinkedList 實現 Deque 介面,即能將LinkedList當作雙端佇列使用。 LinkedList 實現了Cloneable介面,即覆蓋了函式clone(),能克隆。 LinkedList 實現java.io.Serializable介面,這意味著LinkedList支援序列化,能通過序列化去傳輸。 LinkedList 是非同步的。 LinkedList相對於ArrayList來說,它是基於連結串列實現的,支援隨機儲存,但不支援高效的隨機元素訪問。ArrayList的空間浪費主要體現在list列表的結尾預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗相當的空間,就儲存密度來說,ArrayList是優於LinkedList的。 原始碼如下
public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
//實現Serilizable介面時,將不需要序列化的屬性前新增關鍵字transient,序列化物件的時候,這個屬性就不會序列化到指定的目的地中。
transient int size = 0;
//指向首節點
transient Node<E> first;
//指向最後一個節點
transient Node<E> last;
//構建一個空列表
public LinkedList() {
}
//構建一個包含集合c的列表
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
//將節點值為e的節點作為首節點
private void linkFirst(E e) {
final Node<E> f = first;
//構建一個prev值為null,next為f,節點值為e的節點
final Node<E> newNode = new Node<>(null, e, f);
//將newNode作為首節點
first = newNode;
//如果newNode後面沒有節點就將newNode作為最後一個節點
if (f == null)
last = newNode;
//否則就將newNode賦給其prev
else
f.prev = newNode;
//列表長度加一
size++;
modCount++;
}
//將節點值為e的節點作為最後一個節點
void linkLast(E e) {
final Node<E> l = last;
//構建一個prev值為l,next為null,節點值為e的節點
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
//在非空節點succ之前插入節點e
void linkBefore(E e, Node<E> succ) {
final Node<E> pred = succ.prev;
//將succ前面的節點和succ作為其prev和next
final Node<E> newNode = new Node<>(pred, e, succ);
//然後將newNode作為succ的prev
succ.prev = newNode;
//如果原來succ是首節點,則將newNode設定為首節點
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
//釋放非空的首節點f
private E unlinkFirst(Node<E> f) {
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
//將first節點後面的節點設為首節點
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
//釋放非空的尾節點l
private E unlinkLast(Node<E> l) {
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}
//刪除非空節點x
E unlink(Node<E> x)
{
final E element = x.item;
final Node<E> next = x.next; //x後面的節點
final Node<E> prev = x.prev; //x前面的節點
if (prev == null) {
first = next;
} else {
prev.next = next;
x.prev = null;
}
if (next == null) {
last = prev;
} else {
next.prev = prev;
x.next = null;
}
x.item = null;
size--;
modCount++;
return element;
}
//返回列表首節點元素值
public E getFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
//返列表尾節點元素值
public E getLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
//移除首節點
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
//刪除尾節點
public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
//在列表首部插入節點e
public void addFirst(E e) {
linkFirst(e);
}
//在列表尾部插入節點e
public void addLast(E e) {
linkLast(e);
}
//判斷列表中是否包含有元素o
public boolean contains(Object o) {
return indexOf(o) != -1;
}
//返回列表長度大小
public int size() {
return size;
}
//在列表尾部插入元素
public boolean add(E e) {
linkLast(e);
return true;
}
//刪除元素為o的節點
public boolean remove(Object o)
{
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
//將集合c中所有元素新增到列表的尾部
public boolean addAll(Collection<? extends E> c) {
return addAll(size, c);
}
//從指定的位置index開始,將集合c中的元素插入到列表中
public boolean addAll(int index, Collection<? extends E> c) {
//首先判斷插入位置的合法性
checkPositionIndex(index);
Object[] a = c.toArray();
int numNew = a.length;
if (numNew == 0)
return false;
Node<E> pred, succ;
if (index == size) {//說明在列表尾部插入集合元素
succ = null;
pred = last;
}
else { //否則,找到index所在的節點
succ = node(index);
pred = succ.prev;
}
for (Object o : a) {
@SuppressWarnings("unchecked") E e = (E) o;
Node<E> newNode = new Node<>(pred, e, null);
if (pred == null)
first = newNode;
else
pred.next = newNode;
pred = newNode;
}
if (succ == null) {
last = pred;
} else {
pred.next = succ;
succ.prev = pred;
}
size += numNew;
modCount++;
return true;
}
//刪除列表中所有節點
public void clear() {
for (Node<E> x = first; x != null; )
{
Node<E> next = x.next;
x.item = null;
x.next = null;
x.prev = null;
x = next;
}
first = last = null;
size = 0;
modCount++;
}
//獲取指定索引位置節點的元素值
public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
//替換指定索引位置節點的元素值
public E set(int index, E element) {
checkElementIndex(index);
Node<E> x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
//在指定索引位置之前插入元素e
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
//刪除指定位置的元素
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
//判斷指定索引位置的元素是否存在
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
//構建 IndexOutOfBoundsException詳細資訊
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//返回指定索引位置的節點
Node<E> node(int index) {
//此處是一個小技巧,當index<size/2時,從列表前半部分開始,否則從後半部分開始
if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}//返回列表中第一次出現o的位置,若不存在則返回-1
public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node<E> x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node<E> x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
//逆向搜尋,返回第一齣現o的位置,不存在則返回-1
public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
for (Node<E> x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
}
//獲取列表首節點元素值
public E peek() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
//獲取列表首節點元素值,若為空則拋異常
public E element() {
return getFirst();
}
//檢索首節點,若空則返回null,不為空則返回其元素值並刪除首節點
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
//檢索首節點,若空則拋異常,不為空則返回其元素值並刪除首節點
public E remove() {
return removeFirst();
}
//在列表尾部增加節點e
public boolean offer(E e) {
return add(e);
}
//在列表首部插入節點e
public boolean offerFirst(E e) {
addFirst(e);
return true;
}
//在列表尾部插入節點e
public boolean offerLast(E e) {
addLast(e);
return true;
}
public E peekFirst() {
final Node<E> f = first;
return (f == null) ? null : f.item;
}
//獲取列表尾節點元素值
public E peekLast() {
final Node<E> l = last;
return (l == null) ? null : l.item;
}
public E pollFirst() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
public E pollLast() {
final Node<E> l = last;
return (l == null) ? null : unlinkLast(l);
}
//入棧
public void push(E e)
{
addFirst(e);
}
//出棧
public E pop() {
return removeFirst();
}
//刪除列表中第一齣現o的節點
public boolean removeFirstOccurrence(Object o) {
return remove(o);
}
//逆向搜尋,刪除第一次出現o的節點
public boolean removeLastOccurrence(Object o) {
if (o == null) {
for (Node<E> x = last; x != null; x = x.prev) {
if (x.item == null) {
unlink(x);
return true;
}
}
} else {
for (Node<E> x = last; x != null; x = x.prev) {
if (o.equals(x.item)) {
unlink(x);
return true;
}
}
}
return false;
}
Vector
Vector也是基於陣列實現的,是一個動態陣列,其容量能自動增長。 Vector的很多實現方法都加入了同步語句,因此是執行緒安全的,可以用於多執行緒環境。 Vector沒有實現Serializable介面,因此它不支援序列化 Vector實現了Cloneable介面,能被克隆,實現了RandomAccess介面,支援快速隨機訪問。
原始碼
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);
// 新建一個數組,陣列容量是initialCapacity
this.elementData = new Object[initialCapacity];
// 設定容量增長係數
this.capacityIncrement = capacityIncrement;
}
// 指定集合的Vector建構函式。
public Vector(Collection<? extends E> c) {
// 獲取“集合(c)”的陣列,並將其賦值給elementData
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);
}
// 將陣列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的改變統計數+1
modCount++;
ensureCapacityHelper(minCapacity);
}
// 設定容量值為 newSize
public synchronized void setSize(int newSize) {
modCount++;
if (newSize > elementCount) {
// 若 "newSize 大於 Vector容量",則調整Vector的大小。
ensureCapacityHelper(newSize);
} else {
// 若 "newSize 小於/等於 Vector容量",則將newSize位置開始的元素都設定為null
for (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() {
// 通過匿名類實現Enumeration
return 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)。
// 若找到,則返回元素的索引值;否則,返回-1
public 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位置的元素值為obj
public 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中的全部元素設為null
for (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 Cloneable
throw 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中的元素o
public boolean remove(Object o) {
return removeElement(o);
}
// 在index位置新增元素element
public 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 work
return (E)oldValue;
}
// 清空Vector
public void clear() {
removeAllElements();
}
// 返回Vector是否包含集合c
public 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 work
int 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();
}
}
Stack
Stack也是通過陣列實現的,特性是先進後出 執行push時(即,將元素推入棧中),是通過將元素追加的陣列的末尾中。 執行peek時(即,取出棧頂元素,不執行刪除),是返回陣列末尾的元素。 執行pop時(即,取出棧頂元素,並將該元素從棧中刪除),是取出陣列末尾的元素,然後將該元素從陣列中刪除 其他的和Vector無不同,Vector有的,Stack都有。
最後是
CopyOnWriteArrayList
這是一個執行緒安全的ArrayList,用於併發環境,在很多方法中用了lock鎖,防止多個寫操作造成資料不一致問題。原理如下 CopyOnWriteArrayList對讀操作,是不做處理,和普通的ArrayList效能一樣。而在寫操作(修改時),會先拷貝一份,實現新舊版本的分離,然後在拷貝的版本上進行修改操作,修改完後,將其更新至就版本中。 舉一個新增元素的例子
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock(); //加鎖,防止多個寫操作造成資料不一致問題;
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1); //構造一個新陣列,並將舊的資料拷貝至新的陣列中;
newElements[len] = e; //對新陣列執行add操作;
setArray(newElements);//將新陣列更新至arrays
return true;
} finally {
lock.unlock(); //釋放鎖;
}
}