LinkedList源码解析

1.概览

LinkedList是List的另一个实现类,底层以双向链表维持,因为不存在数组,故不会扩容。

2.主要流程

2.1底层定义

维护两个节点:头节点和尾节点,Node为双向链表

    /*** Pointer to first node.* Invariant: (first == null && last == null) ||*            (first.prev == null && first.item != null)*/transient Node<E> first;/*** Pointer to last node.* Invariant: (first == null && last == null) ||*            (last.next == null && last.item != null)*/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;}}

2.2初始化

LinkedList初始化可分为两种情况:无参构造、指定集合构造

无参构造

无参构造什么也不做,只初始化一个空list

    /*** Constructs an empty list.*/public LinkedList() {}

指定集合构造

首先初始化一个空的list,再把入参数集合中的元素添加进链表。

    /*** Constructs a list containing the elements of the specified* collection, in the order they are returned by the collection's* iterator.** @param  c the collection whose elements are to be placed into this list* @throws NullPointerException if the specified collection is null*/public LinkedList(Collection<? extends E> c) {// 1.初始化空链表this();// 2.添加集合所有元素addAll(c);}
    /*** Appends all of the elements in the specified collection to the end of* this list, in the order that they are returned by the specified* collection's iterator.  The behavior of this operation is undefined if* the specified collection is modified while the operation is in* progress.  (Note that this will occur if the specified collection is* this list, and it's nonempty.)** @param c collection containing elements to be added to this list* @return {@code true} if this list changed as a result of the call* @throws NullPointerException if the specified collection is null*/public boolean addAll(Collection<? extends E> c) {// 第一个参数表示插入位置,size为当前链表大小,表示从尾部插入return addAll(size, c);}

在将集合中的所有元素插入链表时,首先检查插入的位置是否合法,否则抛出IndexOutOfBoundsException

    /*** Inserts all of the elements in the specified collection into this* list, starting at the specified position.  Shifts the element* currently at that position (if any) and any subsequent elements to* the right (increases their indices).  The new elements will appear* in the list in the order that they are returned by the* specified collection's iterator.** @param index index at which to insert the first element*              from the specified collection* @param c collection containing elements to be added to this list* @return {@code true} if this list changed as a result of the call* @throws IndexOutOfBoundsException {@inheritDoc}* @throws NullPointerException if the specified collection is null*/public boolean addAll(int index, Collection<? extends E> c) {// 1.检查插入位置checkPositionIndex(index);// 2.集合转数组,空集合则直接return falseObject[] a = c.toArray();int numNew = a.length;if (numNew == 0)return false;// 3.构造前序节点,尾插法前序节点为last,否则去查找index位置的节点Node<E> pred, succ;if (index == size) {succ = null;pred = last;} else {succ = node(index);pred = succ.prev;}// 4.遍历插入for (Object o : a) {@SuppressWarnings("unchecked") E e = (E) o;Node<E> newNode = new Node<>(pred, e, null);if (pred == null)first = newNode;elsepred.next = newNode;pred = newNode;}if (succ == null) {last = pred;} else {pred.next = succ;succ.prev = pred;}// 5.更新size和modCountsize += numNew;modCount++;return true;}

2.3插入

默认插入(尾部)

默认是尾部插入,直接操作last节点

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

头部插入

直接操作头节点

    /*** Inserts the specified element at the beginning of this list.** @param e the element to add*/public void addFirst(E e) {linkFirst(e);}

指定位置插入

会确认index是否合法,其次查找到index的节点,然后插入

    /*** 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);if (index == size)linkLast(element);elselinkBefore(element, node(index));}

2.4删除

与插入类似

    /*** Removes the element at the specified position in this list.  Shifts any* subsequent elements to the left (subtracts one from their indices).* Returns the element that was removed from the list.** @param index the index of the element to be removed* @return the element previously at the specified position* @throws IndexOutOfBoundsException {@inheritDoc}*/public E remove(int index) {checkElementIndex(index);return unlink(node(index));}/*** Unlinks non-null node x.*/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;}

3.结论

  • LinkedList底层是双向链表的数据结构,因此不需要扩容
  • LinkedList不支持随机读写,读写的时间复杂度是O(n),但是不需要移动前后元素

LinkedList源码解析相关推荐

  1. 面试官系统精讲Java源码及大厂真题 - 06 LinkedList 源码解析

    06 LinkedList 源码解析 智慧,不是死的默念,而是生的沉思. --斯宾诺莎 引导语 LinkedList 适用于集合元素先入先出和先入后出的场景,在队列源码中被频繁使用,面试也经常问到,本 ...

  2. Java集合类框架源码分析 之 LinkedList源码解析 【4】

    上一篇介绍了ArrayList的源码分析[点击看文章],既然ArrayList都已经做了介绍,那么作为他同胞兄弟的LinkedList,当然必须也配拥有姓名! Talk is cheap,show m ...

  3. Java集合---LinkedList源码解析

    一.源码解析 1. LinkedList类定义 2.LinkedList数据结构原理 3.私有属性 4.构造方法 5.元素添加add()及原理 6.删除数据remove() 7.数据获取get() 8 ...

  4. 万字长文之JDK1.8的LinkedList源码解析

    1.前言 上一篇文章我们看了List集合的数组实现JDK1.8的ArrayList 源码解析,走过路过不要错过,本篇文章我们将介绍 List 集合的链表实现 LinkedList. 2.整体架构 和 ...

  5. 数据结构-LinkedList源码解析

    可以关注我的微信公众号:xiaobei109208,每周一篇技术分享哦. "各位周末好呀-" "啊呸,程序员哪里来的周末" ​ 前两天怀着激动的心,颤抖的手写了 ...

  6. 【Java深入研究】2、JDK 1.8 LinkedList源码解析

    LinkedList是一个实现了List接口和Deque接口的双端链表.  有关索引的操作可能从链表头开始遍历到链表尾部,也可能从尾部遍历到链表头部,这取决于看索引更靠近哪一端.  LinkedLis ...

  7. LinkedList源码解析(jdk1.8)

    本篇介绍的LinkedList是List接口的另一种实现,它的底层是基于双向链表实现的,它具有插入删除快而查找修改慢的特点,此外,通过对双向链表的操作还可以实现队列和栈的功能. 一.类的继承 publ ...

  8. Java 集合系列(4): LinkedList源码深入解析1

    戳上面的蓝字关注我们哦! 精彩内容 精选java等全套视频教程 精选java电子图书 大数据视频教程精选 java项目练习精选 概要 前面,我们已经学习了ArrayList,并了解了fail-fast ...

  9. Java集合(二二): LinkedList源码剖析

    目录 1.LinkedList简介 2.LinkedList数据结构 3.ArrayList源码分析LinkedList3.ArrayList源码分析 3.1 ArrayList继承结构和层次关系Li ...

  10. 有关LinkedList常用方法的源码解析

    jdk1.7.0_79  上文里解析了有关ArrayList中的几个常用方法的源码--<有关ArrayList常用方法的源码解析>,本文将对LinkedList的常用方法做简要解析. Li ...

最新文章

  1. 原来这样调优可以攻破MySQL性能瓶颈
  2. java ee 下版本_将旧版本从Java EE 5减少到7
  3. 【GPU编程】体绘制传输函数-分类(Volume Rendering Transfer function:Pre- VS Post-Classification)
  4. (44)System Verilog数组逻辑运算
  5. wps多人协作后怎么保存_白酒开瓶后怎么保存?
  6. jQuery - 获取内容和属性
  7. 201621123083 《Java程序设计》第9周学习总结
  8. POJ3080Blue Jeans
  9. python实现A星算法(寻路)
  10. 解决窗口桌面管理器内存占用过高,系统更新,核显驱动异常造成的内存泄漏问题。
  11. 06 Halcon 点云平面度测量
  12. arcgis打开Excel文件显示没有注册类的解决方案
  13. 解决方案模板(标题立问题简述)
  14. 写在工作的第十年: 谈一谈专注和基础的重要性
  15. python爬取猫猫图
  16. 一个小时学会 MySQL 数据库
  17. 带滑动侧边栏的联系人界面
  18. 计算机无纸化考试知识点,面对无纸化考试 2020高会考场上最怕什么?
  19. 通过棘轮轻松实现原型移动应用程序
  20. SOAP Web Services 简介

热门文章

  1. (STM32F103ZET6)SG90舵机的驱动程序
  2. 互联网入口,一个正在消失的“黑洞”
  3. 手写原笔迹输入_手写原笔迹
  4. HTTPS请求过程图解
  5. 信号能量、功率、功率谱密度、自相关函数公式总结
  6. 数字频率系数测试软件,基于单片机简易数字频率计设计方案汇总
  7. ps4html5播放器,PS4迎来全新媒体播放器 支持多种视频音频格式
  8. rssi参数获取_如何获取WlanGetNetworkBssList函数返回值的Rssi值
  9. applyTo、renderTo 区别
  10. windows net 命令详解