LinkedList源码解析

简介

一个非同步的双链表集合,双链表的数据结构示意图如下:

 在LinkedList内部包含一个Node的内部类 ,这个内部类是每一个元素的信息。

private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;
}

从Node的代码中可以非常清楚的看到,每个元素中包含每个元素、以及上一个元素、下一个元素的指针。

重要方法分析

 link

link 相关方法包括linkFirst、linkLast、linkBefore,主要是为了插入一个element,并且和当前链表完成双向绑定。在这里可以和arrayList进行对比,这里可以动态的插入元素,并且不需要进行扩容操作。下面以linkLast为例进行分析

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

1.LinkedList的last赋予临时变量l;

2.linkLast方法中会创建新的Node实例,LinkedList的last会赋予当前Node的prev,赋值prev完成了双指针链表的单向链接。

3.LinkedList的last会指向给newNode既新创建的Node实例。

4.判断临时变量f,其实也是newNode的prev是否为空,如果为空newNode,说明LinkeList集合现在是一个空集合,这时把newNode也赋值给LinkedList的first。

5.如果临时变量l不为空,说明集合已经不为空,把newNode赋值给l.next,完成双指针链表的双向绑定。

node

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

获取指定下标的节点数据,这里和arrayList的查询形成鲜明的对比,arrayList只需要查询数组的下标即可,但是在这里必须要遍历节点。虽然根据size/2进行优化,但是随着N的增加,时间复杂度也必然增加。

unlink

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.item = null;
    size--;
    modCount++;
    return element;
}

1.移除prev引用

如果Node的prev为空,说明当前节点为头部节点,那么把Node的next指向LinkedList的first。

如果Node的prev不为空,那么把prev.next指向Node.next,并且把Node.next置为空。

 

2.移除next引用

如果Node的next为空,说明当前节点是最后一个节点,那么把Node的prev指向LinkedList的last。

如果Node的next不为空,那么把next.prev指向Node.prev,并且把Node.prev置为空。

3.在步骤1、2中完成了双指针的摘链,剩下完成node置空、size--等业务操作。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值