public class LinkedList<E>
extends AbstractSequentialList<E>
implements List<E>, Deque<E>, Cloneable, java.io.Serializable
{
由上源码可知:
LinkedList 是一个继承于AbstractSequentialList的双向链表。
LinkedList 实现 List 接口,能对它进行队列操作。
LinkedList 实现 Deque 接口,(Deque就是双向队列的接口),即能将LinkedList当作双端队列使用。
LinkedList 实现了Cloneable接口,即覆盖了函数clone(),能克隆。
LinkedList 实现java.io.Serializable接口,这意味着LinkedList支持序列化,能通过序列化去传输。LinkedList 是非同步的。
1.构造函数
transient Node<E> first;//指向第一个节点的指针。
transient Node<E> last;//指向最后一个节点的指针。
public LinkedList() {
}
/*
* 按照集合的迭代器返回元素的顺序,构造包含指定集合的元素的列表
*/
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}
LinkedLIst的构造函数主要分为两种,一种是有参构造,一种是无参构造
2.元素的插入
/**
/**
在此列表的开头插入指定的元素。
*/
public void addFirst(E e) {
linkFirst(e);
}
/**
将指定的元素追加到此列表的末尾
*/
public void addLast(E e) {
linkLast(e);
}
/*
在此列表中的指定位置插入指定的元素。将当前位于该位置的元素(如果有的话)和任何后续元素 移到右边(在其索引中添加一个元素)。
*/
public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
*/
由上源码可以看到在LinkedList中插入元素的时候,主要有三种情况:1.头插;2.尾插;3.在指定位置插入元素(当指定位置存在元素的时候,将当前位于该位置的元素(如果有的话)和任何后续元素 移到右边)
3.元素的删除
/**
移除此列表中指定位置的元素。向左移动任何后续元素(从其索引中减去一个元素)。返回从列表中删除的元素。
*/
public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
/**
删除链表中指定元素,如果指定元素存在,则从此列表中移除指定元素的第一个匹配项。如果此列表不包含元素,则它将保持不变。
*/
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;
}
LinkedList中删除元素的时候,只需要改变指针,对比ArrayList,当需要进行频繁的插入、删除操作的时候,选择LinkedList,因为在链表中进行插入删除操作,不需要像ArrayLIst一样对数据进行整体的移动。
4.遍历
public ListIterator<E> listIterator(int index) {
checkPositionIndex(index);
return new ListItr(index);
}
private class ListItr implements ListIterator<E> {
private Node<E> lastReturned;
private Node<E> next;
private int nextIndex;
private int expectedModCount = modCount;
ListItr(int index) {
// assert isPositionIndex(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++;
}
public void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (modCount == expectedModCount && nextIndex < size) {
action.accept(next.item);
lastReturned = next;
next = next.next;
nextIndex++;
}
checkForComodification();
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
}
private class DescendingIterator implements Iterator<E> {
private final ListItr itr = new ListItr(size());
public boolean hasNext() {
return itr.hasPrevious();
}
public E next() {
return itr.previous();
}
public void remove() {
itr.remove();
}
}
LinkedList有两种遍历方式,分别是Iterator、和逆向遍历ListIterator;Iterator中具备的功能只有hashNext(),next(),remove(); ListIterator中具备着对被遍历的元素进行增删改查的方法,可以对元素进行逆向遍历。