我们进入LinkedList的源码,可看出它的继承关系:
public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable {}
- LinkedList是一个继承于AbatractSequentialList的双向链表。它也可以被当作堆栈、队列或双端队列进行操作。
AbstractSequentialList实现了get(int index)、set(int index, E element)、add(int index, E element)和remove(int index)这些方法。这些接口都是随机访问List的,LinkedList是双向链表,既然它继承AbstractSequentialList,就相当于已经实现了“get(int index)”这些接口,可以支持随机访问了。
此外,如果我们需要通过AbstractSequentialList实现一个自己的列表,只需要扩展此类,并提供listIterator()和size()方法的实现即可。若要实现不可修改的列表,则需要实现列表迭代器的hashNext、next、hashPrevious、previous和index方法即可。
- LinkedList实现了List接口,能对它进行队列操作。
- LinkedList实现了Deque接口,即能将LinkedList当作双端队列使用
- LinkedList实现了java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。
- LinkedList是非同步的。
LinkedList的构造函数和API:
LinkedList的API
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)
Iterator<E> descendingIterator()
E element()
E get(int location)
E getFirst()
E getLast()
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator<E> listIterator(int 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)
boolean remove(Object object)
E removeFirst()
boolean removeFirstOccurrence(Object o)
E removeLast()
boolean removeLastOccurrence(Object o)
E set(int location, E object)
int size()
<T> T[] toArray(T[] contents)
Object[] toArray()
LinkedList包含三个重要的成员:
first、
last和
size;
first是双向链表的表头,last是双向链表的尾节点,size是双向链表中的节点个数。
透过LinkedList源码总结一下:
- LinkedList是通过双向链表去实现的。(链表通过一个指向下一个元素地址的引用将链表中的元素串起来。)
- 从LinkedList的实现方式中可以看出,它不存在容量不足的问题,因为是链表。
- LinkedList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写出“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
- LinkdedList的克隆函数,即是将全部元素克隆到一个新的LinkedList中。
- 由于LinkedList实现了Deque,而Deque接口定义了在双端队列两端访问元素的方法。提供插入、移除和检查元素的方法。
- LinkedList可以作为FIFO(先进先出)的队列,作为FIFO的队列时,下标的方法等价:
队列方法 等效方法
add(e) addLast(e)
offer(e) offerLast(e)
remove() removeFirst()
poll() pollFirst()
element() getFirst()
peek() peekFirst()
- LinkedList可以作为LIFO(后进先出)的栈,作为LIFO的栈时,下标的方法等价:
栈方法 等效方法
push(e) addFirst(e)
pop() removeFirst()
peek() peekFirst()
LinkedList的遍历:
LinkedList支持多种遍历方式,建议不要采用随机访问的方式去遍历LinkedList,而采用逐个遍历的方式。
(1)通过Iterator迭代器遍历
for(Iterator iter = list.iterator(); iter.hasNext();)
iter.next();
(2)通过快速随机访问遍历
int size = list.size();
for (int i=0; i<size; i++) {
list.get(i);
}
(3)通过for循环遍历
for (Integer integ:list)
;
(4)通过pollFirst()或pollLast()来遍历
while(list.pollFirst() != null)
;
while(list.pollLast() != null)
;
(5)通过removeFirst()或removeLast()来遍历
while(list.removeFirst() != null)
;
while(list.removeLast() != null)
;
遍历LinkedList时,使用removeFirst()或removeLast()效率最高。但是用它们遍历会删除原始数据;若只是单纯的取数据,而不删除,建议用迭代器方式或者for-each方式。
无论如何,千万不要用随机访问去遍历LinkedList!
例题:请使用LinkedList来模拟一个堆栈或者队列数据结构。LinkedList适合用来实现堆栈与队列。
解:堆栈:先进后出,后进先出;队列:先进先出
代码示例-队列
class DuiLie {
private LinkedList link;
public DuiLie(){
link = new LinkedList();
}
//队列添加元素的功能
public void myAdd(Object obj){
link.addLast(obj);
}
//队列取出元素的功能、
public Object myGet(){
return link.removeLast();
}
public boolean isNull(){
return link.isEmpty();
}
}
public class LinkedTest{
public static void main(String args[]){
DuiLie dl = new DuiLie();
dl.myAdd("abc1");
dl.myAdd("abc2");
dl.myAdd("abc3");
dl.myAdd("abc4");
while(!dl.isNull()){
System.out.println(dl.myGet());
}
}
}