1.初始化

public LinkedList() {
}

并未开辟任何类似于数组一样的存储空间,那么链表是如何存储元素的呢?

2.Node类型

存储到链表中的元素会被封装为一个Node类型的结点。并且链表只需记录第一个结点的位置和最后一个结点的位置。然后每一个结点,前后连接,就可以串起来变成一整个链表。

transient Node<E> first;//指向链表的第一个结点transient Node<E> last;//指向链表的最后一个结点//LinkedList中有一个内部类Node类型 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;}
}

3.添加元素

public boolean add(E e) {//默认链接到链表末尾
    linkLast(e);return true;
}
void linkLast(E e) {//用l记录当前链表的最后一个结点对象final Node<E> l = last;//创建一个新结点对象,并且指定当前新结点的前一个结点为lfinal Node<E> newNode = new Node<>(l, e, null);//当前新结点就变成了链表的最后一个结点last = newNode;if (l == null)//如果当前链表是空的,那么新结点对象,同时也是链表的第一个结点first = newNode;else//如果当前链表不是空的,那么最后一个结点的next就指向当前新结点l.next = newNode;//元素个数增加size++;//修改次数增加modCount++;
}

4.删除元素

public boolean remove(Object o) {//分o是否是null讨论,从头到尾找到要删除的元素o对应的Node结点对象,然后删除if (o == null) {for (Node<E> x = first; x != null; x = x.next) {if (x.item == null) {unlink(x);return true;}}} else {for (Node<E> x = first; x != null; x = x.next) {if (o.equals(x.item)) {unlink(x);return true;}}}return false;
}
E unlink(Node<E> x) {final E element = x.item;//用next记录被删除结点的后一个结点final Node<E> next = x.next;//用prev记录被删除结点的前一个结点final Node<E> prev = x.prev;if (prev == null) {//如果删除的是第一个结点,那么被删除的结点的后一个结点将成为第一个结点first = next;} else {//否则被删除结点的前一个结点的next应该指向被删除结点的后一个结点prev.next = next;//断开被删除结点与前一个结点的关系x.prev = null;}if (next == null) {//如果删除的是最后一个结点,那么被删除结点的前一个结点将变成最后一个结点last = prev;} else {//否则被删除结点的后一个结点的prev应该指向被删除结点的额前一个结点next.prev = prev;//断开被删除结点与后一个结点的关系x.next = null;}//彻底把被删除结点变成垃圾对象x.item = null;//元素个数减少size--;//修改次数增加modCount++;return element;}

5.指定位置插入元素

public void add(int index, E element) {//检查索引位置的合理性
    checkPositionIndex(index);if (index == size)//如果位置是在最后,那么链接到链表的最后
        linkLast(element);else//否则在链表中间插入//node(index)表示找到index位置的Node对象
        linkBefore(element, node(index));
}void linkBefore(E e, Node<E> succ) {// pred记录被插入位置的前一个结点final Node<E> pred = succ.prev;//构建一个新结点final Node<E> newNode = new Node<>(pred, e, succ);//把新结点插入到succ的前面succ.prev = newNode;
    //如果被插入点是链表的开头,那么新结点变成了链表头if (pred == null)first = newNode;else//否则pred的next就变成了新结点pred.next = newNode;//元素个数增加size++;//修改次数增加modCount++;}

6.总结

对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高。因为不涉及到移动元素,只需要修改前后结点的关系。也不需要涉及到扩容

此类虽然提供按照索引查找与操作的方法,但是效率不高,如果需要按索引操作,那么建议使用动态数组

转载于:https://www.cnblogs.com/duoduotouhenying/p/10136441.html

LinkedList的源码分析(基于jdk1.8)相关推荐

  1. HashSet及LinkedHashSet源码分析(基于JDK1.6)

    Java容器类的用途是"保存对象",分为两类:Map--存储"键值对"组成的对象:Collection--存储独立元素.Collection又可以分为List和 ...

  2. 吐血整理:Java线程池源码分析(基于JDK1.8建议收藏)

    文章目录 一.引言 二.线程池的参数介绍 1.ThreadPoolExecutor的UML图 三.线程池的使用 1.线程池的工作原理 2.线程池类型 2.1.newCachedThreadPool使用 ...

  3. ConcurrentHashMap源码分析(2)——JDK1.8的实现

    ConcurrentHashMap源码分析(1)--JDK1.7的实现 前言 在JDK1.7版本上,ConcurrentHashMap还是通过分段锁来实现的,Segment的数量制约着并发量.在JDK ...

  4. ConcurrentHashMap源码分析(1)——JDK1.7的实现

    ConcurrentHashMap源码分析 ConcurrentHashMap源码分析(2)--JDK1.8的实现 前言 ConcurrentHashMap是线程安全且高效的HashMap的实现,在并 ...

  5. AsyncHttpClient源码分析-基于Netty的连接池实现

    原文地址:asynchttpclient源码分析-基于Netty的连接池实现 最近项目重构,有了个机会更多接触一个有别于HttpAsyncClient的异步网络框架AsyncHttpClient,是个 ...

  6. Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法

    Spark资源调度机制源码分析--基于spreadOutApps及非spreadOutApps两种资源调度算法 1.spreadOutApp尽量平均分配到每个executor上: 2.非spreadO ...

  7. uboot源码分析(基于S5PV210)之启动第一阶段

    目录 一.start.S引入 1.u-boot.lds中找到start.S入口 2.SourceInsight中如何找到文件 3.SI中找文件技巧 二.start.S解析 1.不简单的头文件包含 2. ...

  8. ConcurrentHashMap源码解析——基于JDK1.8

    ConcurrentHashMap源码解析--基于JDK1.8 前言 这篇博客不知道写了多久,总之就是很久,头都炸了.最开始阅读源码时确实是一脸茫然,找不到下手的地方,真是太难了.下面的都是我自己阅读 ...

  9. LinkedList的源码分析(三)

    前面两篇通过源码分析了LinkedList的一些基本方法,这一篇将这些方法做一个整体汇总整理,看看哪些方法的作用是相同的,以及他们在使用中的一个分类,因为LinkedList可作为栈.队列.双端队列使 ...

  10. iostat IO统计原理linux内核源码分析----基于单通道SATA盘

    iostat IO统计原理linux内核源码分析----基于单通道SATA盘 先上一个IO发送submit_bio流程图,本文基本就是围绕该流程讲解. 内核版本 3.10.96 详细的源码注释:htt ...

最新文章

  1. 信息记录拉取失败_天猫入驻为什么失败?猫店侠做详细解读
  2. Django 入门项目案例开发(上)
  3. 深度对比Python(Numpy,Scipy)与Matlab的数值精度
  4. 设置透明色有残留怎么办_无尘车间装修,无尘车间内部光线不好怎么办?
  5. VMware vSphere 6简单部署---VCSA( vCenter Server Appliance)部署
  6. magic number
  7. “我在小公司混,有没有资格去知名技术大会上做分享?”
  8. 基于 CNN 和迁移学习的农作物病害识别方法研究
  9. 代码手写UI,xib和StoryBoard间的博弈,以及Interface Builder的一些小技巧
  10. Garbled Circuits介绍 - 4 混淆电路的优化
  11. (附源码)计算机毕业设计SSM基于远程协作的汽车故障诊断系统
  12. 直播搭建软件开发直播搭建技术流程解决方案
  13. 热烈庆祝女朋友的生日
  14. proftpd的一些简单配置
  15. Opengl ES之矩阵变换
  16. 用AdGuard Home搭建一个内部的DNS服务器,开启局域网内无广告和追踪的浏览体验
  17. Linux常用基础命令(巨全)你想要的我都有❀
  18. 【虚幻引擎UE】UE5 简单实现范围计算并绘制圆圈
  19. 8点1氪|苹果第一财季营收843亿美元;VIPKID拟融资4-5亿美元;工信部称5G终端将于年中推出...
  20. 轮胎规格怎么看?“3T”指数到底是什么?换轮胎前必读!

热门文章

  1. 分布式文件存储FastDFS之配置Nginx模块
  2. Testing Flutter apps翻译-使用 Mockito 模拟依赖项
  3. [转]C++学习步骤
  4. Ubuntu双网卡绑定
  5. 打造线上的大数据风控,我们发现了这三个坑
  6. puppet的配置清单书写
  7. Chrome Vimium 快捷键
  8. 2008新建域时失败问题
  9. 一个类windows系统的效果图
  10. BT5新的征程!全民***计划!