0
点赞
收藏
分享

微信扫一扫

LinkedList源码分析

简介

底层的数据结构为双向链表

LinkedList源码分析_赋值

LinkedList 优缺点

  • 优点
  • 插入和删除时只需要添加或删除前后对象的引用,插入较快
  • 缺点:
  • 在内存中存储不连续,只能通过遍历查询,效率相对较低
  • 占内存 双向指针
  • 线程不安全 并没有什么保护措施

链表不存在容量不足的问题
LinkedList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写出“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。
LinkdedList的克隆函数,即是将全部元素克隆到一个新的LinkedList中。
LinkedList可以作为FIFO(先进先出)的队列
LinkedList可以作为LIFO(后进先出)的栈

两种构造方法

transient int size = 0;

transient Node<E> last;

transient Node<E> first;

//无参构造
public LinkedList() {
}
// 不能设置长度
// 数组构造
public LinkedList(Collection<? extends E> c) {
this();
addAll(c);
}

节点

 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;
}
}

add( E e)

public boolean add(E e) {
linkLast(e);
return true;
}
//
void linkLast(E e) {
final Node<E> l = last;// 赋值最后一个l
//从创建新的节点 prev 指向 上一个节点 l 也就是last
final Node<E> newNode = new Node<>(l, e, null);
// last 走一个节点
last = newNode;
// 赋值 l.next 的节点
// 为空的时候就是第一次添加的时候
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}

addFirst(E e)

 public void addFirst(E e) {
linkFirst(e); // 在头部添加
}

private void linkFirst(E e) {
// 记录头指针
final Node<E> f = first;
// 创建新的节点prev 指向 f
final Node<E> newNode = new Node<>(null, e, f);
first = newNode;
// 判断头节点是否为空 也就是第一次添加
if (f == null)
// last 为空
last = newNode;
else
// 指向新的节点
f.prev = newNode;
size++;
// 记录操作次数(增加 或者 删除的记录)
modCount++;
}

addLast(E e)

public void addLast(E e) {
linkLast(e);
}
// 实质和add 方法 一个样
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++;
}

remove(Object o)

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) {
// assert x != null;
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 为空 则释放了资源
x.item = null;
size--; //长度减一
modCount++; //记录次数
return element; // 返回删除的值
}

removeFirst()

public E removeFirst() {
final Node<E> f = first;
//头节点为空 异常
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}

// 删除头节点
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC 帮助gc回收
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}

removeLast()

public E removeLast() {
final Node<E> l = last;
if (l == null)
throw new NoSuchElementException();
return unlinkLast(l);
}
//删除尾节点
private E unlinkLast(Node<E> l) {
// assert l == last && l != null;
final E element = l.item;
final Node<E> prev = l.prev;
l.item = null;
l.prev = null; // help GC
last = prev;
// prev == null 只有一个元素
if (prev == null)
first = null;
else
prev.next = null;
size--;
modCount++;
return element;
}

get(int index)

public E get(int index) {

checkElementIndex(index);
return node(index).item;
}

// 检查元素索引
private void checkElementIndex(int index) {
if (!isElementIndex(index))
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
//判断下标是否超标
private boolean isElementIndex(int index) {
return index >= 0 && index < size;
}

// 搜索元素
Node<E> node(int index) {
// assert isElementIndex(index);
// size /2 在左边 直接遍历到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;
}
}

set(index x,E element)

public E set(int index, E element) {
// 检查 下标是否溢出
checkElementIndex(index);
// 查找 下标为index 的元素
Node<E> x = node(index);
//赋值
E oldVal = x.item;
x.item = element;
// 返回 被删除的值
return oldVal;
}

indexOf(Object o)

 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;
}


举报

相关推荐

0 条评论