1 使用方法
LinkedList基於雙端鏈表實現,可以作爲棧、隊列或者雙端隊列使用。
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
LinkedList繼承了AbstractSequentialList,實現了get等方法;
LinkedList實現了Deque接口,可以作爲雙端隊列使用;
LinkedList實現Cloneable接口重寫了接口定義的clone()方法,可以使用clone()複製鏈表。
LinkedList實現 java.io.Serializable接口使LinkedList支持序列化。
1.1 方法介紹
LinkedList提供了增加,彈出,獲取元素等操作,具體提供的方法如下:
boolean add(E object) //在末尾增加一個元素
void add(int location, E object) //在指定位置增加元素
boolean addAll(Collection<? extends E> collection) //在末尾加入一組元素
boolean addAll(int location, Collection<? extends E> collection) //從指定位置開始加一組元素
void addFirst(E object) //在表頭增加一個元素
void addLast(E object) //在表尾增加一個元素
void clear() //清空鏈表
Object clone() //複製一個元素
boolean contains(Object object) //判斷是否包含object
Iterator<E> descendingIterator() //逆序迭代器
E element() //獲取鏈表第一個元素,不存在會拋出異常
E get(int location) //獲取location位置的元素,不存在會拋出異常
E getFirst() //獲取鏈表第一個元素,不存在會拋出異常
E getLast() //獲取鏈表最後一個元素,不存在會拋出異常
int indexOf(Object object) //獲取object第一次出現的位置
int lastIndexOf(Object object) //獲取object最後一次出現的位置
ListIterator<E> listIterator(int location) //從location開始的迭代器
boolean offer(E o) //在末尾增加一個元素
boolean offerFirst(E e) //在表頭增加一個元素
boolean offerLast(E e) //在表尾增加一個元素
E peek() //獲取表頭元素,不存在不會拋出異常
E peekFirst() //獲取表頭元素,不存在不會拋出異常
E peekLast() //獲取表尾元素,不存在不會拋出異常
E poll() //彈出表頭元素
E pollFirst() //彈出表頭元素
E pollLast() //彈出表尾元素
E pop() //彈出表頭元素,不存在會拋異常
void push(E e) //在表頭增加一個元素
E remove() //刪除最後一個元素
E remove(int location) //刪除location位置的元素
boolean remove(Object object) //刪除第一個出現的object
E removeFirst() //刪除第一個元素
boolean removeFirstOccurrence(Object o) //刪除第一個出現的o
E removeLast() //刪除最後一個元素
boolean removeLastOccurrence(Object o) //刪除最後一個出現的o
E set(int location, E object) //將location位置設置爲object
int size() //鏈表大小
<T> T[] toArray(T[] contents) //轉換爲T類型的數組
Object[] toArray() //轉換爲Object類型的數組
1.2 使用示例
public class TestLinkedList {
public void testLinkedList() throws Exception {
LinkedList<String> linkedList = new LinkedList<String>();
linkedList.add("a"); //在表尾增加元素
linkedList.add("b");
printLinkedList(linkedList);
linkedList.addFirst("pre-a"); //在表頭增加元素
System.out.println("鏈表中包含 'a' 元素:" + linkedList.contains("a")); //包含元素判斷
System.out.println("鏈表的第一個元素: " + linkedList.peek());
System.out.println("鏈表的最後一個元素: " + linkedList.peekLast());
printLinkedList(linkedList);
System.out.println("獲取刪除鏈表的第一個元素: " + linkedList.poll());
printLinkedList(linkedList);
System.out.println("獲取並彈出鏈表的最後一個元素" + linkedList.pollLast());
printLinkedList(linkedList);
linkedList.offer("d");
linkedList.offer("e");
linkedList.offer("f");
printLinkedList(linkedList);
System.out.println("第三個元素爲: " + linkedList.get(2)); //獲取第三個元素
System.out.println("將第四個元素設置爲g: " + linkedList.set(3, "g"));
printLinkedList(linkedList);
//轉換成數組
String[] arr = (String[]) linkedList.toArray(new String[0]);
for (String e: arr) {
System.out.print(e + " ");
}
}
protected void printLinkedList(LinkedList<String> linkedList) {
Iterator<String> iterator = linkedList.iterator();
System.out.print("linkList包含的元素有: ");
while (iterator.hasNext()) {
System.out.print(iterator.next() + " ");
}
System.out.println("\n");
}
}
運行結果如下:
linkList包含的元素有: a b
鏈表中包含 'a' 元素:true
鏈表的第一個元素: pre-a
鏈表的最後一個元素: b
linkList包含的元素有: pre-a a b
獲取刪除鏈表的第一個元素: pre-a
linkList包含的元素有: a b
獲取並彈出鏈表的最後一個元素b
linkList包含的元素有: a
linkList包含的元素有: a d e f
第三個元素爲: e
將第四個元素設置爲g: f
linkList包含的元素有: a d e g
a d e g
2 源碼分析
2.1 add方法
public boolean add(E e) { //在末尾增加一個元素
linkLast(e);
return true;
}
void linkLast(E e) {
final Node<E> l = last; //末尾元素
final Node<E> newNode = new Node<>(l, e, null); //申請一個值爲e的元素,前一個元素爲l,後一個爲null
last = newNode; //新元素爲最後一個元素
if (l == null) //空鏈表
first = newNode;
else
l.next = newNode;
size++; //鏈表長度增加
modCount++;
}
2.2 addFirst方法
public void addFirst(E e) { //在表頭增加元素
linkFirst(e);
}
private void linkFirst(E e) {
final Node<E> f = first; //表頭元素
final Node<E> newNode = new Node<>(null, e, f); //申請一個值爲e的元素,前一個元素爲null,後一個元素爲f
first = newNode; //新元素爲表頭元素
if (f == null) //空鏈表
last = newNode;
else
f.prev = newNode;
size++; //長度增加
modCount++;
}
2.3 peek方法
public E peek() {
final Node<E> f = first; //獲取表頭元素
return (f == null) ? null : f.item; //返回null或者表頭元素的值
}
2.4 poll方法
public E poll() {
final Node<E> f = first;
return (f == null) ? null : unlinkFirst(f);
}
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item; //獲取第一個元素的值
final Node<E> next = f.next; //獲取第二個元素
f.item = null; //將第一個元素置爲null
f.next = null; // help GC,
first = next; //將原有的第二個元素設爲頭元素
if (next == null) //原鏈表只有一個元素,此時鏈表爲空
last = null;
else
next.prev = null; //頭元素的前置元素爲null
size--;
modCount++;
return element;
}
2.5 toArray(T[] contents) 方法
public <T> T[] toArray(T[] a) {
if (a.length < size) //a長度小於鏈表長度,則重新申請一個長度爲size的數組
a = (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
int i = 0;
Object[] result = a;
for (Node<E> x = first; x != null; x = x.next) //爲數組賦值
result[i++] = x.item;
if (a.length > size) //如果長度大於鏈表長度,最後一個元素後一個設爲null,表示數組結束
a[size] = null;
return a;
}
參考:
[1] http://blog.csdn.net/crave_shy/article/details/17440835
[2] http://blog.csdn.net/wanghao109/article/details/13287877
[3] http://fjohnny.iteye.com/blog/696750