java链表list_java LinkedList(链表)

本文详细介绍了Java集合框架中的LinkedList实现,包括其内部结构、主要方法如add、remove、contains等的操作,以及作为List、Deque接口实现的特性。通过对源码的解析,展示了LinkedList如何高效地进行链表操作。
摘要由CSDN通过智能技术生成

packagejava.util;importjava.util.function.Consumer;public class LinkedList

extends AbstractSequentialList

implements List, Deque, Cloneable, java.io.Serializable

{transient int size = 0;transient Nodefirst;transient Nodelast;publicLinkedList() {

}public LinkedList(Collection extends E>c) {this();

addAll(c);

}private voidlinkFirst(E e) {final Node f =first;final Node newNode = new Node<>(null, e, f);

first=newNode;if (f == null)

last=newNode;elsef.prev=newNode;

size++;

modCount++;

}voidlinkLast(E e) {final Node l =last;final Node newNode = new Node<>(l, e, null);

last=newNode;if (l == null)

first=newNode;elsel.next=newNode;

size++;

modCount++;

}void linkBefore(E e, Nodesucc) {//assert succ != null;

final Node pred =succ.prev;final Node newNode = new Node<>(pred, e, succ);

succ.prev=newNode;if (pred == null)

first=newNode;elsepred.next=newNode;

size++;

modCount++;

}private E unlinkFirst(Nodef) {//assert f == first && f != null;

final E element =f.item;final Node next =f.next;

f.item= null;

f.next= null; //help GC

first =next;if (next == null)

last= null;elsenext.prev= null;

size--;

modCount++;returnelement;

}private E unlinkLast(Nodel) {//assert l == last && l != null;

final E element =l.item;final Node prev =l.prev;

l.item= null;

l.prev= null; //help GC

last =prev;if (prev == null)

first= null;elseprev.next= null;

size--;

modCount++;returnelement;

}

E unlink(Nodex) {//assert x != null;

final E element =x.item;final Node next =x.next;final Node prev =x.prev;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++;returnelement;

}publicE getFirst() {final Node f =first;if (f == null)throw newNoSuchElementException();returnf.item;

}publicE getLast() {final Node l =last;if (l == null)throw newNoSuchElementException();returnl.item;

}publicE removeFirst() {final Node f =first;if (f == null)throw newNoSuchElementException();returnunlinkFirst(f);

}publicE removeLast() {final Node l =last;if (l == null)throw newNoSuchElementException();returnunlinkLast(l);

}public voidaddFirst(E e) {

linkFirst(e);

}public voidaddLast(E e) {

linkLast(e);

}public booleancontains(Object o) {return indexOf(o) != -1;

}public intsize() {returnsize;

}public booleanadd(E e) {

linkLast(e);return true;

}public booleanremove(Object o) {if (o == null) {for (Node x = first; x != null; x =x.next) {if (x.item == null) {

unlink(x);return true;

}

}

}else{for (Node x = first; x != null; x =x.next) {if(o.equals(x.item)) {

unlink(x);return true;

}

}

}return false;

}public boolean addAll(Collection extends E>c) {returnaddAll(size, 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;

Nodepred, succ;if (index ==size) {

succ= null;

pred=last;

}else{

succ=node(index);

pred=succ.prev;

}for(Object o : a) {

@SuppressWarnings("unchecked") E e =(E) o;

Node newNode = new Node<>(pred, e, null);if (pred == null)

first=newNode;elsepred.next=newNode;

pred=newNode;

}if (succ == null) {

last=pred;

}else{

pred.next=succ;

succ.prev=pred;

}

size+=numNew;

modCount++;return true;

}public voidclear() {//Clearing all of the links between nodes is "unnecessary", but://- helps a generational GC if the discarded nodes inhabit//more than one generation//- is sure to free memory even if there is a reachable Iterator

for (Node x = first; x != null; ) {

Node next =x.next;

x.item= null;

x.next= null;

x.prev= null;

x=next;

}

first= last = null;

size= 0;

modCount++;

}//Positional Access Operations

public E get(intindex) {

checkElementIndex(index);returnnode(index).item;

}public E set(intindex, E element) {

checkElementIndex(index);

Node x =node(index);

E oldVal=x.item;

x.item=element;returnoldVal;

}public void add(intindex, E element) {

checkPositionIndex(index);if (index ==size)

linkLast(element);elselinkBefore(element, node(index));

}public E remove(intindex) {

checkElementIndex(index);returnunlink(node(index));

}private boolean isElementIndex(intindex) {return index >= 0 && index

}private boolean isPositionIndex(intindex) {return index >= 0 && index <=size;

}private String outOfBoundsMsg(intindex) {return "Index: "+index+", Size: "+size;

}private void checkElementIndex(intindex) {if (!isElementIndex(index))throw newIndexOutOfBoundsException(outOfBoundsMsg(index));

}private void checkPositionIndex(intindex) {if (!isPositionIndex(index))throw newIndexOutOfBoundsException(outOfBoundsMsg(index));

}

Node node(intindex) {//assert isElementIndex(index);

if (index < (size >> 1)) {

Node x =first;for (int i = 0; i < index; i++)

x=x.next;returnx;

}else{

Node x =last;for (int i = size - 1; i > index; i--)

x=x.prev;returnx;

}

}public intindexOf(Object o) {int index = 0;if (o == null) {for (Node x = first; x != null; x =x.next) {if (x.item == null)returnindex;

index++;

}

}else{for (Node x = first; x != null; x =x.next) {if(o.equals(x.item))returnindex;

index++;

}

}return -1;

}public intlastIndexOf(Object o) {int index =size;if (o == null) {for (Node x = last; x != null; x =x.prev) {

index--;if (x.item == null)returnindex;

}

}else{for (Node x = last; x != null; x =x.prev) {

index--;if(o.equals(x.item))returnindex;

}

}return -1;

}//Queue operations.

publicE peek() {final Node f =first;return (f == null) ? null: f.item;

}publicE element() {returngetFirst();

}publicE poll() {final Node f =first;return (f == null) ? null: unlinkFirst(f);

}publicE remove() {returnremoveFirst();

}public booleanoffer(E e) {returnadd(e);

}public booleanofferFirst(E e) {

addFirst(e);return true;

}public booleanofferLast(E e) {

addLast(e);return true;

}publicE peekFirst() {final Node f =first;return (f == null) ? null: f.item;

}publicE peekLast() {final Node l =last;return (l == null) ? null: l.item;

}publicE pollFirst() {final Node f =first;return (f == null) ? null: unlinkFirst(f);

}publicE pollLast() {final Node l =last;return (l == null) ? null: unlinkLast(l);

}public voidpush(E e) {

addFirst(e);

}publicE pop() {returnremoveFirst();

}public booleanremoveFirstOccurrence(Object o) {returnremove(o);

}public booleanremoveLastOccurrence(Object o) {if (o == null) {for (Node x = last; x != null; x =x.prev) {if (x.item == null) {

unlink(x);return true;

}

}

}else{for (Node x = last; x != null; x =x.prev) {if(o.equals(x.item)) {

unlink(x);return true;

}

}

}return false;

}public ListIterator listIterator(intindex) {

checkPositionIndex(index);return newListItr(index);

}private class ListItr implements ListIterator{private NodelastReturned;private Nodenext;private intnextIndex;private int expectedModCount =modCount;

ListItr(intindex) {//assert isPositionIndex(index);

next = (index == size) ? null: node(index);

nextIndex=index;

}public booleanhasNext() {return nextIndex

}publicE next() {

checkForComodification();if (!hasNext())throw newNoSuchElementException();

lastReturned=next;

next=next.next;

nextIndex++;returnlastReturned.item;

}public booleanhasPrevious() {return nextIndex > 0;

}publicE previous() {

checkForComodification();if (!hasPrevious())throw newNoSuchElementException();

lastReturned= next = (next == null) ?last : next.prev;

nextIndex--;returnlastReturned.item;

}public intnextIndex() {returnnextIndex;

}public intpreviousIndex() {return nextIndex - 1;

}public voidremove() {

checkForComodification();if (lastReturned == null)throw newIllegalStateException();

Node lastNext =lastReturned.next;

unlink(lastReturned);if (next ==lastReturned)

next=lastNext;elsenextIndex--;

lastReturned= null;

expectedModCount++;

}public voidset(E e) {if (lastReturned == null)throw newIllegalStateException();

checkForComodification();

lastReturned.item=e;

}public voidadd(E e) {

checkForComodification();

lastReturned= null;if (next == null)

linkLast(e);elselinkBefore(e, next);

nextIndex++;

expectedModCount++;

}public void forEachRemaining(Consumer super E>action) {

Objects.requireNonNull(action);while (modCount == expectedModCount && nextIndex

action.accept(next.item);

lastReturned=next;

next=next.next;

nextIndex++;

}

checkForComodification();

}final voidcheckForComodification() {if (modCount !=expectedModCount)throw newConcurrentModificationException();

}

}private static class Node{

E item;

Nodenext;

Nodeprev;

Node(Node prev, E element, Nodenext) {this.item =element;this.next =next;this.prev =prev;

}

}public IteratordescendingIterator() {return newDescendingIterator();

}private class DescendingIterator implements Iterator{private final ListItr itr = newListItr(size());public booleanhasNext() {returnitr.hasPrevious();

}publicE next() {returnitr.previous();

}public voidremove() {

itr.remove();

}

}

@SuppressWarnings("unchecked")private LinkedListsuperClone() {try{return (LinkedList) super.clone();

}catch(CloneNotSupportedException e) {throw newInternalError(e);

}

}publicObject clone() {

LinkedList clone =superClone();//Put clone into "virgin" state

clone.first = clone.last = null;

clone.size= 0;

clone.modCount= 0;//Initialize clone with our elements

for (Node x = first; x != null; x =x.next)

clone.add(x.item);returnclone;

}publicObject[] toArray() {

Object[] result= newObject[size];int i = 0;for (Node x = first; x != null; x =x.next)

result[i++] =x.item;returnresult;

}

@SuppressWarnings("unchecked")public T[] toArray(T[] a) {if (a.length

a=(T[])java.lang.reflect.Array.newInstance(

a.getClass().getComponentType(), size);int i = 0;

Object[] result=a;for (Node x = first; x != null; x =x.next)

result[i++] =x.item;if (a.length >size)

a[size]= null;returna;

}private static final long serialVersionUID = 876323262645176354L;private voidwriteObject(java.io.ObjectOutputStream s)throwsjava.io.IOException {//Write out any hidden serialization magic

s.defaultWriteObject();//Write out size

s.writeInt(size);//Write out all elements in the proper order.

for (Node x = first; x != null; x =x.next)

s.writeObject(x.item);

}

@SuppressWarnings("unchecked")private voidreadObject(java.io.ObjectInputStream s)throwsjava.io.IOException, ClassNotFoundException {//Read in any hidden serialization magic

s.defaultReadObject();//Read in size

int size =s.readInt();//Read in all elements in the proper order.

for (int i = 0; i < size; i++)

linkLast((E)s.readObject());

}

@Overridepublic Spliteratorspliterator() {return new LLSpliterator(this, -1, 0);

}/**A customized variant of Spliterators.IteratorSpliterator*/

static final class LLSpliterator implements Spliterator{static final int BATCH_UNIT = 1 << 10; //batch array size increment

static final int MAX_BATCH = 1 << 25; //max batch array size;

final LinkedList list; //null OK unless traversed

Node current; //current node; null until initialized

int est; //size estimate; -1 until first needed

int expectedModCount; //initialized when est set

int batch; //batch size for splits

LLSpliterator(LinkedList list, int est, intexpectedModCount) {this.list =list;this.est =est;this.expectedModCount =expectedModCount;

}final intgetEst() {int s; //force initialization

final LinkedListlst;if ((s = est) < 0) {if ((lst = list) == null)

s= est = 0;else{

expectedModCount=lst.modCount;

current=lst.first;

s= est =lst.size;

}

}returns;

}public long estimateSize() { return (long) getEst(); }public SpliteratortrySplit() {

Nodep;int s =getEst();if (s > 1 && (p = current) != null) {int n = batch +BATCH_UNIT;if (n >s)

n=s;if (n >MAX_BATCH)

n=MAX_BATCH;

Object[] a= newObject[n];int j = 0;do { a[j++] = p.item; } while ((p = p.next) != null && j

current=p;

batch=j;

est= s -j;return Spliterators.spliterator(a, 0, j, Spliterator.ORDERED);

}return null;

}public void forEachRemaining(Consumer super E>action) {

Node p; intn;if (action == null) throw newNullPointerException();if ((n = getEst()) > 0 && (p = current) != null) {

current= null;

est= 0;do{

E e=p.item;

p=p.next;

action.accept(e);

}while (p != null && --n > 0);

}if (list.modCount !=expectedModCount)throw newConcurrentModificationException();

}public boolean tryAdvance(Consumer super E>action) {

Nodep;if (action == null) throw newNullPointerException();if (getEst() > 0 && (p = current) != null) {--est;

E e=p.item;

current=p.next;

action.accept(e);if (list.modCount !=expectedModCount)throw newConcurrentModificationException();return true;

}return false;

}public intcharacteristics() {return Spliterator.ORDERED | Spliterator.SIZED |Spliterator.SUBSIZED;

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值