详解Java 集合系列(三)—— LinkedList

 更新时间:2019年04月01日 09:49:46   作者:那一叶随风  
这篇文章主要介绍了Java 集合系列(三)—— LinkedList,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

LinkedList

LinkedList是一种可以在任何位置进行高效地插入和删除操作的有序序列。
它的最基本存储结构是一个节点:每个节点将存储对象,以及前后节点的引用。

结构图

从上面的结构图中,我们可以了解到 ListedList 底层是基于双向链表实现的。
围起来的可以看成 LinkedList 类,它定义了三个 transient 成员变量:first、last、size。这三个变量是整个 LinkedList 类的关键点。

  1. 由于是双向链表(每个node都有保存前后节点的引用),因此我们不管是由 first 还是 last 节点开始迭代,都可以将整个链表的数据找出来;
  2. 在查询、随机插入以及set等操作都有涉及 size 判断;
  3. 由于 LinkedList 是双向链表,类中只存储了首尾两个节点,因此查询第n个元素都要从头遍历进行查找。

 源码分析

add(E e)  源码分析

/**
  * Appends the specified element to the end of this list.
  *
  * <p>This method is equivalent to {@link #addLast}.
  *
  * @param e element to be appended to this list
  * @return {@code true} (as specified by {@link Collection#add})
  */
 public boolean add(E e) {
  linkLast(e);
  return true;
 }
 
 /**
  * Links e as last element.
  */
 void linkLast(E e) {
  final Node<E> l = last;        // 将当前最后一个元素寄存在 l
  final Node<E> newNode = new Node<>(l, e, null);  // new 一个新节点:pre的引用为l;存储元素为e;next的引用为null
  last = newNode;          // 将新节点引用覆盖成员变量 last
  if (l == null)          
   first = newNode;        // 若l为null,说明之前链表为空,此时新节点为首个元素
  else
   l.next = newNode;        // 否则,更新l的next引用
  size++;            // size+1
  modCount++;           // 非查询操作 modCount 都会 +1
 }

add(int index, E element) 方法分析

/**
  * Inserts the specified element at the specified position in this list.
  * Shifts the element currently at that position (if any) and any
  * subsequent elements to the right (adds one to their indices).
  *
  * @param index index at which the specified element is to be inserted
  * @param element element to be inserted
  * @throws IndexOutOfBoundsException {@inheritDoc}
  */
 public void add(int index, E element) {
  checkPositionIndex(index); // 检查 index 是否大于 size

  if (index == size)
   linkLast(element);  // 直接在链表末尾追加
  else
   linkBefore(element, node(index)); // 插入index 节点前面
 }
 
 
 // 检查 index 是否超出范围 超出则抛出 IndexOutOfBoundsException
 private void checkPositionIndex(int index) {
  if (!isPositionIndex(index))
   throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
 }

 /**
  * Tells if the argument is the index of a valid position for an
  * iterator or an add operation.
  */
 private boolean isPositionIndex(int index) {
  return index >= 0 && index <= size;
 }
 
 
 
 /**
  * 根据 index 查找 node
  * 该方法利用了双向链表的特性,index 距离哪个链表头近就从哪边开始开始遍历
  * 时间复杂度为 O(n/2);
  * 当 index 接近 size 的中间值时,效率最低
  * Returns the (non-null) Node at the specified element index.
  */
 Node<E> node(int index) {
  // assert isElementIndex(index);

  if (index < (size >> 1)) {   // size 右移一位(除以2)
   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;
  }
 }

优缺点

优点

增删元素效率高(只需要更新节点附近的引用即可)

缺点

由于查询需要进行遍历,因此效率低

知识脑图

以上所述是小编给大家介绍的Java 集合系列(三)—— LinkedList详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

相关文章

  • 利用5分钟快速搭建一个springboot项目的全过程

    利用5分钟快速搭建一个springboot项目的全过程

    Spring Boot的监控能够使开发者更好地掌控应用程序的运行状态,下面这篇文章主要给大家介绍了关于如何利用5分钟快速搭建一个springboot项目的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-05-05
  • 聊聊Redis二进制数组Bitmap

    聊聊Redis二进制数组Bitmap

    这篇文章主要介绍了Redis二进制数组Bitmap,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • java模拟hibernate一级缓存示例分享

    java模拟hibernate一级缓存示例分享

    这篇文章主要介绍了java模拟hibernate一级缓存示例,需要的朋友可以参考下
    2014-03-03
  • Lombok的@Accessors使用说明

    Lombok的@Accessors使用说明

    这篇文章主要介绍了Lombok的@Accessors使用说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • java中元素排序Comparable和Comparator的区别

    java中元素排序Comparable和Comparator的区别

    本文主要介绍了java中元素排序Comparable和Comparator的区别,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Eclipse中Properties和yml配置文件注释乱码的解决

    Eclipse中Properties和yml配置文件注释乱码的解决

    这篇文章主要介绍了Eclipse中Properties和yml配置文件注释乱码的解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Spring的@CrossOrigin注解使用与CrossFilter对象自定义详解

    Spring的@CrossOrigin注解使用与CrossFilter对象自定义详解

    这篇文章主要介绍了Spring的@CrossOrigin注解使用与CrossFilter对象自定义详解,跨域,指的是浏览器不能执行其他网站的脚本,它是由浏览器的同源策略造成的,是浏览器施加的安全限制,所谓同源是指,域名,协议,端口均相同,需要的朋友可以参考下
    2023-12-12
  • IDEA2023 配置使用Docker的详细教程

    IDEA2023 配置使用Docker的详细教程

    这篇文章主要介绍了IDEA2023 配置使用Docker的详细教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-07-07
  • Java的线程池ThreadPoolExecutor及多种线程池实现详解

    Java的线程池ThreadPoolExecutor及多种线程池实现详解

    这篇文章主要介绍了Java的线程池ThreadPoolExecutor及多种线程池实现详解,ThreadPoolExecutor 使用 int 的高 3 位来表示线程池状态,低 29 位表示线程数量,之所以将信息存储在一个变量中,是为了保证原子性,需要的朋友可以参考下
    2024-01-01
  • servlet Cookie使用方法详解(六)

    servlet Cookie使用方法详解(六)

    这篇文章主要为大家详细介绍了servlet Cookie的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09

最新评论