简介
基于双向链表实现 可当做栈和队列使用 非线程安全 实现Serializable接口、Cloneable接口,支持序列化和克隆
源码
构造方法
public class LinkedList <E >
extends AbstractSequentialList <E >
implements List <E >, Deque <E >, Cloneable , java .io .Serializable {
transient int size = 0 ;
transient Node<E> first;
transient Node<E> last;
public LinkedList() {
}
public LinkedList(Collection<? extends E> c) {
this ();
addAll(c);
}
}
方法
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);
}
private E unlinkFirst (Node<E> f) {
final E element = f.item;
final Node<E> next = f.next;
f.item = null ;
f.next = null ;
first = next;
if (next == null )
last = null ;
else
next.prev = null ;
size--;
modCount++;
return element;
}
public E removeLast () {
final Node<E> l = last;
if (l == null )
throw new NoSuchElementException();
return unlinkLast(l);
}
private E unlinkLast (Node<E> l) {
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null ;
l.prev = null ;
last = prev;
if (prev == null )
first = null ;
else
prev.next = null ;
size--;
modCount++;
return element;
}
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);
first = newNode;
if (f == null )
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
public void addLast (E e) {
linkLast(e);
}
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null );
last = newNode;
if (l == null )
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
public boolean contains (Object o) {
return indexOf(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 ;
}
public int size () {
return size;
}
public boolean add (E e) {
linkLast(e);
return true ;
}
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 ;
}
E unlink(Node<E> x) {
final E element = x.item;
final Node<E> next = x.next;
final Node<E> 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++;
return element;
}
public boolean addAll (Collection<? extends E> c) {
return addAll(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 ;
Node<E> pred, 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<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 ;
}
Node<E> node(int index) {
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;
}
}
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;
}
public void add (int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
void linkBefore(E e, Node<E> succ) {
final Node<E> pred = succ.prev;
final Node<E> newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null )
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
public E remove (int index) {
checkElementIndex(index);
return unlink(node(index));
}
public E poll () {
final Node<E> f = first;
return (f == null ) ? null : unlinkFirst(f);
}
public boolean offer (E e) {
return add(e);
}
public E remove () {
return removeFirst();
}
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 ;
}
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 void push (E e) {
addFirst(e);
}
public E pop () {
return removeFirst();
}
public ListIterator<E> listIterator (int index) {
checkPositionIndex(index);
return new ListItr(index);
}
public Object[] toArray () {
Object[] result = new Object[size];
int i = 0 ;
for (Node<E> x = first; x != null ; x = x.next)
result[i++] = x.item;
return result;
}
@SuppressWarnings ("unchecked" )
public <T> T[] toArray (T[] a) {
if (a.length < 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)
a[size] = null ;
return a;
}
迭代器
private class ListItr implements ListIterator<E> {
private Node<E> lastReturned;
private Node<E> next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
next = (index == size) ? null : node(index);
nextIndex = index;
}
public boolean hasNext () {
return nextIndex < size;
}
public E next () {
checkForComodification();
if (!hasNext())
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.item;
}
public boolean hasPrevious () {
return nextIndex > 0 ;
}
public E previous () {
checkForComodification();
if (!hasPrevious())
throw new NoSuchElementException();
lastReturned = next = (next == null ) ? last : next.prev;
nextIndex--;
return lastReturned.item;
}
public int nextIndex () {
return nextIndex;
}
public int previousIndex () {
return nextIndex - 1 ;
}
public void remove () {
checkForComodification();
if (lastReturned == null )
throw new IllegalStateException();
Node<E> lastNext = lastReturned.next;
unlink(lastReturned);
if (next == lastReturned)
next = lastNext;
else
nextIndex--;
lastReturned = null ;
expectedModCount++;
}
public void set (E e) {
if (lastReturned == null )
throw new IllegalStateException();
checkForComodification();
lastReturned.item = e;
}
public void add (E e) {
checkForComodification();
lastReturned = null ;
if (next == null )
linkLast(e);
else
linkBefore(e, next);
nextIndex++;
expectedModCount++;
}
Node的结构
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
Node(Node<E> prev, E element, Node<E> next) {
this .item = element;
this .next = next;
this .prev = prev;
}
}
总结
基于双向链表,保持有头指针跟尾指针,但头尾不相连 两个构造方法:默认构造方法、传进来集合的构造方法 允许元素为null,在查找元素的时候分null和非null查找 遍历链表的时候,有一个加速操作:if (index < (size >> 1))//折半,这样可以节省一半的时间 对增删的操作效率高,无需移动节点 队列操作:
public E peek ()//获取第一个元素的值,如果没有元素则返回null
public E element ()//获取第一个元素的值,如果没有元素则抛异常
public E poll ()//删除队头
public E remove ()//删除队头,如果队头为null 之抛出异常
public boolean offer (E e) //添加元素到队后面
public void push (E e) //添加
public E pop ()//删除栈顶