LinkedList

1、概述

LinkedList 是 List 和 Deque 接口的双向链表实现,所有实现都不是同步的,非线程安全。

它的插入、删除操作比 ArrayList 更高效,随机访问的效率相比较更差。

2、继承类实现接口

public class LinkedList<E>
    extends AbstractSequentialList<E>
    implements List<E>, Deque<E>, Cloneable, java.io.Serializable

LinkedList 继承自 AbstractSequenceList,实现了 List、Deque、Cloneable、java.io.Serializable 接口。AbstractSequenceList 提供了 List 接口骨干性的实现以减少实现 List 接口的复杂度,Deque 接口定义了双端队列的操作。

在 LinkedList 中,除了本身自己的方法外,还提供了一些可以使其作为栈、队列或者双端队列的方法。

3、变量

transient int size = 0;  // 长度
transient Node<E> first;  // 头指针
transient Node<E> last;  // 尾指针

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

4、构造方法

public LinkedList() {
     // 构造一个空链表
}

public LinkedList(Collection<? extends E> c) {
   
    this();
    addAll(c);  // 根据c构造LinkedList
}

public boolean addAll(Collection<? extends E> c) {
   
    return addAll(size, c);
}

public boolean addAll(int index, Collection<? extends E> c) {
   
    checkPositionIndex(index);  // 检查范围

    Object[] a = c.toArray();
    int numNew = a.length;
    if (numNew == 0)  // 如果c为空就返回false
        return false;

    Node<E> pred, succ;  // 前驱和后继节点
    if (index == size) {
     // 如果到最后add,那么前驱就是last,后继为null
        succ = null;
        pred = last;
    } else {
     // 否则后继为index处节点,前驱为后继前一个
        succ = node(index);
        pred = succ.prev;
    }

    for (Object o : a) {
   
        @SuppressWarnings("unchecked") E e = (E) o;
        Node<E> newNode = new Node<>(pred, e, null);  // 这里确定了前驱节点,找后继节点就行
        if (pred == null) // 最前面添加就将newNode赋给first
            first = newNode;
        else  // 否则让前驱节点的后继为newNode
            pred.next = newNode;
        pred = newNode;
    }

    if (succ == null) {
     // 后继为空说明last为最后添加的Node
        last = pred;
    } else {
     // 否则将pred和succ连起来
        pred.next = succ;
        succ.prev = pred;
    }

    size += numNew;
    modCount++;
    return true;
}

private void checkPositionIndex(int index) {
   
    if (!isPositionIndex(index))
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

private boolean isPositionIndex(int index) {
   
    return index >= 0 && index <= size;
}

5、重要方法

linkFirst(E e):将节点插入链表头。

private void linkFirst(E e) {
   
    final Node<E> f = first;  // f记录之前的链表头
    final Node<E> newNode = new Node<>(null, e, f);  // 新节点,pre为空,next为f
    first = newNode;  // 新节点赋给first
  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值