LinkedList是基于链表的,继承了AbstractSequentialList<E>,实现了List<E>、Deque<E>、Cloneable、Serializable接口,其中Deque<E>为双端队列,LinkedList是双向循环链表。
(一)LinkedList的俩个属性:
(1)privatetransient Entry<E> header = newEntry<E>(null, null,null);
(2)privatetransientintsize = 0;
size即LinkedList中存储的元素个数,header就是链表的头结点,同ArrayList一样,元素也被transient修饰,不可序列化。Entry<E>为LinkedList的内部类:(相当于一个实体类,由于LinkedList是基于链表的,每个元素只与他的前一个元素和后一个元素有关,所以每个元素除了包含本身,还包括他的前一个元素和后一个元素)
privatestaticclass Entry<E> {
E element; //存储的元素
Entry<E> next; //下一个元素
Entry<E> previous; //前一个元素
Entry(E element,Entry<E> next, Entry<E> previous){
this.element = element;
this.next = next;
this.previous = previous;
}
}
(二)LinkedList的俩个构造方法
(1)public LinkedList() {
header.next = header.previous = header;
}
(2)public LinkedList(Collection<? extends E> c){
this();
addAll(c);
}
(1)初始化一个空链表,从(1)就可以看出LinkedList是一个双向循环链表,(如果不是循环链表,空链表的情况应该是header节点的前一节点和后一节点均为null),此时的结构为:
(2)先初始化一个空链表,然后将集合c添加到此链表,addAll(c)方法如下:(在header前添加c)
publicboolean addAll(Collection<? extendsE> c) {
return addAll(size, c);
}
调用重载方法addAll(int index, Collection<? extends E> c):
publicboolean addAll(intindex,Collection<? extends E>c){
//如果index<0或index>size则抛出异常
if (index < 0 || index > size)
throw new IndexOutOfBoundsException
("Index:"+index+ ", Size: "+size);
Object[] a = c.toArray(); //把集合c转换成数组
intnumNew = a.length; //数组的长度
if(numNew==0)
returnfalse;
modCount++;
//successor指要插入的位置的元素(e的后一个元素),index等于size时,successor
//指向头部header,否则指index处的元素
Entry<E> successor = (index==size ? header : entry(index));
//predecessor是successor的前一个元素(e的前一个元素)
Entry<E> predecessor = successor.previous;
for (inti=0; i<numNew; i++) {
//加入链表的每一个元素
Entry<E> e = newEntry<E>((E)a[i], successor, predecessor);
//predecessor的下一个元素设为e
predecessor.next = e;
//successor的前一个元素predecessor设为e
predecessor = e;
}
//predecessor赋值给successor.previous
successor.previous = predecessor;
size += numNew;
returntrue;
}
双向循环列表要知道每一个元素相邻的前后元素,加入的每一个元素e的之前的元素是predecessor,之后的元素是successor,新加入后predecessor.next变为e,successor.previous变为e。
获得指定位置的元素的entry(intindex)方法为:
private Entry<E> entry(intindex) {
if(index < 0 || index>= size)
thrownew IndexOutOfBoundsException("Index: "+index+ ", Size: "+size);
Entry<E> e= header;
//移位运算:>>为右移,右移一位相当于除以2,右移n位相当于除//以2的n次方,<<为左//移,左移n位相当于乘以2的n次方。使用移位运算代替乘除法效率要高的多。
//在此判断index如果<1/2size则从header往后查找,如果//index>1/2size则从//header往前查找。
if(index < (size>> 1)) {
for(inti = 0; i <= index; i++)
e= e.next;
} else{
for(inti = size; i > index;i--)
e= e.previous;
}
returne;
}
(三)LinkedList的添加方法
//List里的添加方法:
publicboolean add(E e) {
addBefore(e,header);
returntrue;
}
publicvoidadd(intindex, E element) {
addBefore(element, (index==size ? header :
entry(index)));
}
//队列里的添加方法:
publicvoidaddFirst(E e) {
addBefore(e, header.next);
}
publicvoidaddLast(E e) {
addBefore(e,header);
}
publicboolean offer(E e) {
return add(e);
}
publicboolean offerFirst(E e) {
addFirst(e);
returntrue;
}
publicboolean offerLast(E e) {
addLast(e);
returntrue;
}
publicvoidpush(E e) { //栈的实现方法
addFirst(e);
}
可见底层调用的都是addBefore(Ee, Entry<E> entry):
privateEntry<E> addBefore(E e,Entry<E> entry) {
Entry<E> newEntry= new Entry<E>(e, entry,
entry.previous);
//相当于更改指针
newEntry.previous.next= newEntry;
newEntry.next.previous = newEntry;
size++;
modCount++;
returnnewEntry;
}
(四)LinkedList的删除方法
//List里的删除方法:
publicboolean remove(Object o) {
if(o==null){
for (Entry<E> e= header.next; e != header; e= e.next) {
if (e.element==null) {
remove(e);
returntrue;
}
}
} else{
for (Entry<E> e= header.next; e != header; e= e.next) {
if (o.equals(e.element)) {
remove(e);
returntrue;
}
}
}
returnfalse;
}
public E remove(intindex) {
return remove(entry(index));
}
//队列里的删除方法:
public E removeFirst() {
returnremove(header.next);
}
public E removeLast() {
returnremove(header.previous);
}
public E poll() { //当队列为空时返回null
if(size==0)
returnnull;
return removeFirst();
}
public E remove() { //当队列为空时抛出异常
return removeFirst();
}
public E pollFirst() {
if(size==0)
returnnull;
return removeFirst();
}
public E pollLast() {
if(size==0)
returnnull;
return removeLast();
}
public E pop() { //栈的实现方法
return removeFirst();
}
publicboolean removeFirstOccurrence(Object o){
return remove(o);
}
//由于是双向循环链表,header.previous就是最后一个元素,从后往前找
publicboolean removeLastOccurrence(Object o){
if(o==null){
for(Entry<E> e = header.previous; e != header;e = e.previous)
{
if (e.element==null) {
remove(e);
returntrue;
}
}
} else{
for(Entry<E> e = header.previous; e != header;e = e.previous)
{
if(o.equals(e.element)) {
remove(e);
returntrue;
}
}
}
returnfalse;
}
删除的方法底层调用的都是remove(Entry<E>e)方法:
private E remove(Entry<E> e) {
if(e == header)
thrownew NoSuchElementException();
E result = e.element;
//相当于更改指针
e.previous.next = e.next;
e.next.previous = e.previous;
//将e的前后元素以及自身都设为null
e.next = e.previous = null;
e.element = null;
size--;
modCount++;
returnresult;
}
(五)LinkedList的查找方法
//list的查找方法:
public E get(intindex) {
return entry(index).element;
}
publicintindexOf(Object o) {
intindex = 0;
if(o==null){
for (Entry e = header.next; e != header;e = e.next) {
if (e.element==null)
returnindex;
index++;
}
} else{
for (Entry e = header.next; e != header;e = e.next) {
if(o.equals(e.element))
returnindex;
index++;
}
}
return -1;
}
publicintlastIndexOf(Object o) {
intindex = size;
if(o==null){
for (Entry e = header.previous; e != header;e = e.previous) {
index--;
if(e.element==null)
returnindex;
}
} else{
for (Entry e = header.previous; e != header;e = e.previous) {
index--;
if(o.equals(e.element))
returnindex;
}
}
return -1;
}
//Deque的查找方法:
public E getFirst() {
if (size==0)
thrownew NoSuchElementException();
returnheader.next.element;
}
public E getLast() {
if (size==0)
thrownew NoSuchElementException();
returnheader.previous.element;
}
public E peek() { //如果链表为空,返回null
if(size==0)
returnnull;
return getFirst();
}
public E element() { //如果链表为空,抛出异常
return getFirst();
}
public E peekFirst() {
if(size==0)
returnnull;
return getFirst();
}
public E peekLast() {
if(size==0)
returnnull;
return getLast();
}
添加、删除和查找的方法分为List实现和queue实现,因为LinkedList实现了List和Deque接口,当作为List使用时采用List的方法,作为Queue使用时,用队列的方法。
(六)LinkedList的更改方法
//用element替换index处的元素
public E set(intindex, E element){
Entry<E> e= entry(index);
E oldVal = e.element;
e.element = element;
returnoldVal;
}
(七)LinkedList的遍历方法:
//从index处开始遍历,返回一个迭代器
public ListIterator<E> listIterator(intindex) {
returnnew ListItr(index);
}
ListItr是一个内部类:
privateclass ListItr implements ListIterator<E> {
privateEntry<E> lastReturned = header;
privateEntry<E> next;
privateintnextIndex;
privateintexpectedModCount= modCount;
ListItr(intindex) {
if (index < 0 || index> size)
thrownew IndexOutOfBoundsException("Index: "+index+
", Size: "+size);
if (index < (size>> 1)) {
next = header.next;
for(nextIndex=0; nextIndex<index; nextIndex++)
next = next.next;
} else {
next = header;
for(nextIndex=size; nextIndex>index; nextIndex--)
next = next.previous;
}
}
**省略接口里的其他方法**
}
遍历的例子:
publicclass TestLinkedList {
publicstaticvoidmain(String[] args) throws ClassNotFoundException {
LinkedList<String> list = new LinkedList<String>();
list.add("haha");
list.add("heihei");
list.add("xixi");
//获得迭代器,从第二个元素(heihei)开始遍历
Iterator<String> iterator = list.listIterator(1);
while(iterator.hasNext()){
String s= iterator.next();
System.out.println(s);
}
}
}
结果:
(八)其他方法:
//判断list中是否包含o
publicboolean contains(Object o) {
return indexOf(o) != -1;
}
//返回list的大小
publicintsize() {
returnsize;
}
//置空list
publicvoidclear() {
Entry<E> e= header.next;
while (e != header){
Entry<E>next = e.next;
e.next = e.previous = null;
e.element = null;
e= next;
}
header.next = header.previous = header;
size = 0;
modCount++;
}
//cloneList 此处为浅复制
public Object clone() {
LinkedList<E> clone = null;
try {
clone = (LinkedList<E>) super.clone();
} catch (CloneNotSupportedException e){
thrownew InternalError();
}
// Put clone into "virgin" state
clone.header = new Entry<E>(null,null, null);
clone.header.next = clone.header.previous = clone.header;
clone.size = 0;
clone.modCount = 0;
// Initialize clone with our elements
for(Entry<E> e = header.next; e != header;e = e.next)
clone.add(e.element);
returnclone;
}
//把list转换为array
public Object[] toArray() {
Object[] result= new Object[size];
inti = 0;
for (Entry<E> e= header.next; e != header; e = e.next)
result[i++] = e.element;
returnresult;
}
public <T> T[] toArray(T[] a) {
if(a.length < size)
//如果数组的大小<list的大小,创建一个指定类型,指定大小的新数组
a= (T[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
inti = 0;
Object[] result= a;
for(Entry<E> e = header.next; e != header;e = e.next)
result[i++] = e.element;
//如果数组的大小>list的大小,将不用的置空
if(a.length > size)
a[size] = null;
returna;
}
参考资料:http://blog.youkuaiyun.com/jzhf2012/article/details/8540543
http://www.cnblogs.com/ITtangtang/p/3948610.html#a6