尽管数组在连续的存储位置上存放对象的引用,但链表却将每个对象存放在独立的结点中。每个结点还存放着序列中喜爱个结点的引用。在Java程序设计语言中,所有链表实际上都是双向链接的,即每个结点都存放着指向前驱结点的引用。如上图所示。
链表的各个结点类型由LinkedList类的内部类定义,该内部类为:private static class Node
源代码为:
private static class Node {
E item;
Node next;
Node prev;
Node(Node prev, E element, Node next) {
this.item = element;
this.next = next;
this.prev = prev;
}
}
源码解析:
public LinkedList()
public LinkedList() {
}
public LinkedList(Collection extends E> c)
public LinkedList(Collection extends E> c) {
this();
addAll(c);
}
源码解析:
addAll()
方法将形参加入到新的LinkedList类型的对象中private void linkFirst(E e)
方法 private void linkFirst(E e) {
final Node f = first;
final Node newNode = new Node<>(null, e, f);
first = newNode;
if (f == null)
last = newNode;
else
f.prev = newNode;
size++;
modCount++;
}
源码解析:
void linkLast(E e)
方法 void linkLast(E e) {
final Node l = last;
final Node newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
源码解析:
void linkBefore(E e, Node succ)
方法 void linkBefore(E e, Node succ) {
// assert succ != null;
final Node pred = succ.prev;
final Node newNode = new Node<>(pred, e, succ);
succ.prev = newNode;
if (pred == null)
first = newNode;
else
pred.next = newNode;
size++;
modCount++;
}
源码解析:
private E unlinkFirst(Node f)
方法 private E unlinkFirst(Node f) {
// 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;
else
next.prev = null;
size--;
modCount++;
return element;
}
源码解析:
private E unlinkLast(Node l)
方法 private E unlinkLast(Node l) {
// 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;
else
prev.next = null;
size--;
modCount++;
return element;
}
源码解析:
该方法与unlinkFirst
方法类似,再次不赘述
E unlink(Node x)
方法 E unlink(Node x) {
// 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++;
return element;
}
源码解析:
public E getFirst()
方法 public E getFirst() {
final Node f = first;
if (f == null)
throw new NoSuchElementException();
return f.item;
}
源码解析:
public E getLast()
方法 public E getLast() {
final Node l = last;
if (l == null)
throw new NoSuchElementException();
return l.item;
}
源码解析:
public E removeFirst()
方法 public E removeFirst() {
final Node f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
源码解析:
public E removeLast()
方法 public E removeLast() {
final Node l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
源码解析:
- 功能:移除链表中的最后一个结点
- 源码思路:
- (1) 定义一个Node类型的变量l,该变量的值等于last,即当前链表的最后一个结点
- (2) 如果变量l的值等于null,则抛出异常
- (3) 如果变量的值不为null,则调用unlinkFirst方法,将l的值作为形式参数传递进去
public void addFirst(E e)
方法 public void addFirst(E e) {
linkFirst(e);
}
源码解析:
- 功能:向链表中增加一个值为e的结点
- 源码思路:
- (1) 该方法不做任何操作,只是调用linkFirst(e)方法,利用头插法将元素插入链表中
public void addLast(E e)
方法 public void addLast(E e) {
linkLast(e);
}
源码解析:
- 功能:向链表中增加一个值为e的结点
- 源码思路:
- (1) 该方法不做任何操作,只是调用linkLast(e)方法,利用尾插法将元素插入链表中
public boolean contains(Object o)
方法 public boolean contains(Object o) {
return indexOf(o) != -1;
}
源码解析:
- 功能:判断链表中是否有元素o
- 源码思路:
- (1) 该方法不做任何操作,只是调用indexOf方法,来判断indexOf方法的返回值,如果返回值为-1,说明不包含,那么contains返回false,否则返回true
public int size()
方法 public int size() {
return size;
}
源码解析:
- 功能:返回链表中的结点个数
- 源码思路:
- (1) 直接返回该类的size变量的值
public boolean add(E e)
方法 public boolean add(E e) {
linkLast(e);
return true;
}
源码解析:
- 功能:向链表中插入一个元素e,如果插入成功返回true,否则返回false
- 源码思路:
- (1)直接调用linkLast(e)方法,利用尾插法插入元素
public boolean remove(Object o)
方法 public boolean remove(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)
方法 public boolean addAll(Collection extends E> c) {
return addAll(size, c);
}
源码解析:
public boolean addAll(int index, Collection extends E> 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 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 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;
}
源码解析:
public void clear()
方法 public void clear() {
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++;
}
源码解析:
public E get(int index)
方法 public E get(int index) {
checkElementIndex(index);
return node(index).item;
}
源码解析:
public E set(int index, E element)
方法 public E set(int index, E element) {
checkElementIndex(index);
Node x = node(index);
E oldVal = x.item;
x.item = element;
return oldVal;
}
源码解析:
public void add(int index, E element)
方法 public void add(int index, E element) {
checkPositionIndex(index);
if (index == size)
linkLast(element);
else
linkBefore(element, node(index));
}
源码解析:
public E remove(int index)
方法 public E remove(int index) {
checkElementIndex(index);
return unlink(node(index));
}
源码解析:
private boolean isElementIndex(int index)
方法 private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}
源码解析:
private boolean isPositionIndex(int index)
方法 private boolean isPositionIndex(int index) {
return index >= 0 && index <= size;
}
源码解析:
private String outOfBoundsMsg(int index)
方法 private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
源码解析:
private void checkElementIndex(int index)
方法 private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
源码解析:
private void checkPositionIndex(int index)
方法 private void checkPositionIndex(int index) {
if (!isPositionIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
源码解析:
public int indexOf(Object o)
方法 public int indexOf(Object o) {
int index = 0;
if (o == null) {
for (Node x = first; x != null; x = x.next) {
if (x.item == null)
return index;
index++;
}
} else {
for (Node x = first; x != null; x = x.next) {
if (o.equals(x.item))
return index;
index++;
}
}
return -1;
}
源码思路:
public int lastIndexOf(Object o)
方法 public int lastIndexOf(Object o) {
int index = size;
if (o == null) {
for (Node x = last; x != null; x = x.prev) {
index--;
if (x.item == null)
return index;
}
} else {
for (Node x = last; x != null; x = x.prev) {
index--;
if (o.equals(x.item))
return index;
}
}
return -1;
}
源码解析:
功能:从链表尾开始遍历,返回指定结点的索引值
public E peek()
方法 public E peek() {
final Node f = first;
return (f == null) ? null : f.item;
}
源码解析:
源码思路:
(2)如果变量f的值等于null,即链表的第一个结点是null,则返回null,否则返回f的元素值
public E element()
方法 public E element() {
return getFirst();
}
源码解析:
源码思路:
直接调用getFirst方法,执行该操作
public E poll()
方法 public E poll() {
final Node f = first;
return (f == null) ? null : unlinkFirst(f);
}
源码解析: