用java源代码学数据结构<四>: LinkedList 详解(一)

2014-11-24 08:51:45 · 作者: · 浏览: 0
在数据结构中有基本数据类型:线性表。线性表又可以分为顺序表(数组表)和链表。java中典型顺序表有Vector和ArrayList,链表类就是LinkedList。
个人体会:
1.要想gc(垃圾回收器)回收对象,普通的对象只需要设置为null即可,而复合型对象(如Node),它包含两个指针对象和一个元素,必须全部设置为Null才能回收
2.在链表节点进行prev、next等操作时,需要注意空指针异常。对此需要相应的作出判断(例如直接设置为first或last对象等)
3.强烈推荐仔细分析下LinkedList中的ListItr迭代器(特别是针对它的previous和next两种访问方式)
[java]
package java.util;
/*
1.LinkedList是一个双向链表,允许包含null元素
2.LinkedList是线程不同步的。多线程结构化修改
(增加或删除若干个元素,不包括设置元素值)可能造成意想不到的结果
3.可以使用同步对象来封装LinkedList类。也可以在开始对象时使用
List list = Collections.synchronizedList(new LinkedList(...))
*/
public class LinkedList
extends AbstractSequentialList
implements List, Deque, Cloneable, java.io.Serializable
{
/*
典型的双向链表节点类,每个节点有数据,前指针(java中就是对象),后指针
*/
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;
}
}
/*
transient
1.为了在一个特定对象的一个域上关闭serialization,
可以在这个域前加上关键字transient。
2.当一个对象被序列化的时候,transient型变量的值不包括在序列化的表示中,
然而非transient型的变量是被包括进去的。
3.size表示链表的元素数目
*/
transient int size = 0;
//链表头指针
transient Node first;
//链表尾指针
transient Node last;
public LinkedList() {
}
//集合构造函数
public LinkedList(Collection< extends E> c) {
this();
addAll(c);
}
//将e对象设置到链表头
private void linkFirst(E e) {
final Node f = first;
final Node newNode = new Node<>(null, e, f);
//重新设置first指针
first = newNode;
if (f == null)
last = newNode;
else
//如果原来的first不为空,就将原来的first(即f)接到新的first(newNodw)的后面
f.prev = newNode;
size++;
modCount++;
}
//将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
//如果原来的last不为空,就将新的last(即newNode)接到原来的last(l)的后面
l.next = newNode;
size++;
modCount++;
}
//在非空节点succ之前插入对象e
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++;
}
//删除头结点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;
}
//删除尾部节点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