Java容器源码LinkedList原理解析

 更新时间:2020年11月18日 09:14:54   投稿:yaominghui  
这篇文章主要介绍了Java容器源码LinkedList原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

LinkedList简介

LinkedList是一个使用双向链表结构实现的容器,与ArrayList一样,它能动态扩充其长度,LinkedList相较于ArrayList,其任意位置插入速度比ArrayList要快,但是其查询速度要比ArrayList要慢;LinkedList继承自AbstractSequentialList,实现了List、Deque、Cloneable、Serializable接口。

LinkedList UML图如下:

和ArrayList一样,LinkedList也不是一个线程安全的容器。

LinkedList源码分析

构造方法

LinkedList有两个构造方法:

public LinkedList() {
}

//从已有的一个容器创建一个LinkedList对象
public LinkedList(Collection<? extends E> c) {
  this();
  addAll(c);
}

addAll()方法:

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

public boolean addAll(int index, Collection<? extends E> c) {
  //检查index是否溢出
  checkPositionIndex(index);
  
  Object[] a = c.toArray();
  int numNew = a.length;
  if (numNew == 0)
    return false;
  //获取第index位置的node元素和node的前一个元素
  //succ:第index位置的node元素
  //pred:index位置前一个node元素
  Node<E> 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<E> 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;
}

add方法

LinkedList也有两个add方法,如下:

public boolean add(E e) {
  //添加元素到队尾
  linkLast(e);
  return true;
}

public void add(int index, E element) {
  //检查index是否溢出
  checkPositionIndex(index);

  if (index == size)
    //index == size,直接添加到队尾
    linkLast(element);
  else
    //index != size,添加元素到index位置
    linkBefore(element, node(index));
}

linkLast方法:

void linkLast(E e) {
  final Node<E> l = last;
  //新建一个node,将其前一个元素指针指向原链表的最后一个元素
  final Node<E> newNode = new Node<>(l, e, null);
  //更新尾指针
  last = newNode;
  if (l == null)
    //若原last==null说明此时链表就一个元素
    first = newNode;
  else
    //更新原链表尾元素指针
    l.next = newNode;
  size++;
  modCount++;
}

linkBefore方法:

void linkBefore(E e, Node<E> succ) {
  // assert succ != null;
  //获取指定位node元素的前一个元素pred
  final Node<E> pred = succ.prev;
  //新建一个node,将其前指针指向pred元素
  final Node<E> newNode = new Node<>(pred, e, succ);
  //将指定位置的node元素的前指针指向新元素,完成插入
  succ.prev = newNode;
  if (pred == null)
    first = newNode;
  else
    pred.next = newNode;
  size++;
  modCount++;
}

获取指定位置node指针方法node:

Node<E> node(int index) {
  // assert isElementIndex(index);
  //index > size/2时,说明在链表前半段,从前往后搜索
  if (index < (size >> 1)) {
    Node<E> x = first;
    for (int i = 0; i < index; i++)
      x = x.next;
    return x;
  //index < size/2时,从后往前搜索
  } else {
    Node<E> x = last;
    for (int i = size - 1; i > index; i--)
      x = x.prev;
    return x;
  }
}

get方法也比较简单,首先检测index是否溢出,然后直接找到index位置的元素,并返回其item。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringMVC 整合SSM框架详解

    SpringMVC 整合SSM框架详解

    这篇文章主要介绍了SpringMVC 整合SSM框架详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • SpringBoot接入轻量级分布式日志框架(GrayLog)的操作方法

    SpringBoot接入轻量级分布式日志框架(GrayLog)的操作方法

    这篇文章主要介绍了SpringBoot接入轻量级分布式日志框架(GrayLog)的方法,本文通过图文实例相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • SpringBoot整合RabbitMQ 手动应答(简单demo)

    SpringBoot整合RabbitMQ 手动应答(简单demo)

    这篇文章主要介绍了SpringBoot整合RabbitMQ 手动应答 简单demo,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Springcloud Eureka配置及集群代码实例

    Springcloud Eureka配置及集群代码实例

    这篇文章主要介绍了Springcloud Eureka配置及集群代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • Java 实现FTP服务实例详解

    Java 实现FTP服务实例详解

    这篇文章主要介绍了Java 实现FTP服务实例详解的相关资料,需要的朋友可以参考下
    2017-04-04
  • java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP)

    java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP)

    这篇文章主要介绍了java后台实现支付宝支付接口和支付宝订单查询接口(前端为APP),非常具有实用价值,需要的朋友可以参考下
    2018-08-08
  • Java中static与instance的区别及作用详解

    Java中static与instance的区别及作用详解

    这篇文章主要为大家介绍了Java中static与instance的区别及作用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Spring Boot中使用Swagger3.0.0版本构建RESTful APIs的方法

    Spring Boot中使用Swagger3.0.0版本构建RESTful APIs的方法

    Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务,这篇文章主要介绍了Spring Boot中使用Swagger3.0.0版本构建RESTful APIs的方法,需要的朋友可以参考下
    2022-11-11
  • Java线程池队列PriorityBlockingQueue原理分析

    Java线程池队列PriorityBlockingQueue原理分析

    这篇文章主要介绍了Java线程池队列PriorityBlockingQueue原理分析,PriorityBlockingQueue队列是 JDK1.5 的时候出来的一个阻塞队列,但是该队列入队的时候是不会阻塞的,永远会加到队尾,需要的朋友可以参考下
    2023-12-12
  • MyBatis 中 ${}和 #{}的正确使用方法(千万不要乱用)

    MyBatis 中 ${}和 #{}的正确使用方法(千万不要乱用)

    这篇文章主要介绍了MyBatis 中 ${}和 #{}的正确使用方法,本文给大家提到了MyBatis 中 ${}和 #{}的区别,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07

最新评论