LinkedList讲解指南
咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~
🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!
环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8
文章目录
- 前言
- 摘要
- LinkedList
- 概述
- 源代码解析
- 1. 定义
- 2. 节点类Node
- 3. add方法
- 4. get方法
- 5. remove方法
- 存储结构
- 基本操作
- 应用场景案例
- 优缺点分析
- 类代码方法介绍
- 代码分析
- 测试用例
- 测试代码演示
- 测试结果
- 测试代码分析
- 全文小结
- 总结
- 附录源码
- ☀️建议/推荐你
- 📣关于我
前言
在Java开发中,LinkedList是一个非常常见的数据结构,常用于实现栈、队列等数据结构。本文将从Java中LinkedList的基本概念和操作开始,逐步深入,介绍Linkedlist的源代码解析、应用场景案例、优缺点分析以及类代码方法介绍等内容,最后给出测试用例和全文小结。
摘要
本文将介绍Java中LinkedList的基础知识,包括数据结构定义、基本操作、源代码解析等;随后将介绍LinkedList的应用场景案例、优缺点分析以及类代码方法介绍等内容。本文将帮助读者全面了解LinkedList,在实际开发中灵活运用,提升代码效率和质量。
LinkedList
概述
LinkedList属于Java中的集合,是一种线性结构,可以存储不同类型的元素,并且可以动态改变元素数量。LinkedList采用链表的数据结构实现,它的每个节点都保存了下一个节点的内存地址,因此可以实现动态添加、删除和查找等操作。在实际开发中,LinkedList被广泛应用于栈、队列等数据结构的实现;同时也可以用于缓存、列表等场景中。
源代码解析
LinkedList是Java中的一个双向链表实现的集合类,它实现了List和Deque接口,提供了插入、删除、查找等操作方法。接下来我们来分析一下LinkedList的源码。
1. 定义
LinkedList的源码位于java.util包下,其定义如下:
public class LinkedList<E>extends AbstractSequentialList<E>implements List<E>, Deque<E>, Cloneable, java.io.Serializable {transient int size = 0;transient Node<E> first;transient Node<E> last;//...省略部分代码
}
可以看到LinkedList定义了三个成员变量:size表示链表的大小,first表示第一个节点,last表示最后一个节点,这三个变量都是transient类型的,表示不会被序列化。由于LinkedList实现了List接口,因此还需要实现List接口中的抽象方法,这里就不一一列出了。
2. 节点类Node
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;}
}
每个节点包含三个属性:item表示节点存储的元素,next表示下一个节点,prev表示上一个节点。节点类使用了private修饰符,表示只能在LinkedList内部访问。
3. add方法
add方法是LinkedList中最基本的方法之一,用于在链表尾部添加一个元素,其源码如下:
public boolean add(E e) {linkLast(e);return true;
}void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;
}
可以看到,linkLast方法是用于在链表尾部插入节点的,它首先得到链表最后一个节点l,然后创建一个新的节点newNode,并将之前的last节点的next指向newNode。如果链表为空,newNode就成为了第一个节点,否则就将newNode连接在l之后。最后,链表的长度加1。
4. get方法
get方法用于获取链表中指定位置的元素,其源码如下:
public E get(int index) {checkElementIndex(index);return node(index).item;
}Node<E> node(int index) {if (index < (size >> 1)) {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;}
}
可以看到,get方法首先调用了checkElementIndex方法,用于检查index是否越界。然后调用node方法,获取指定位置的节点。node方法根据index的值,选择从头部或尾部开始遍历链表,找到目标节点并返回其元素值。
5. remove方法
remove方法用于从链表中删除指定位置的元素,其源码如下:
public E remove(int index) {checkElementIndex(index);return unlink(node(index));
}E unlink(Node<E> x) {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--;return element;
}
可以看到,remove方法首先调用了checkElementIndex方法,用于检查index是否越界。然后调用unlink方法,用于删除指定节点。unlink方法首先保存了目标节点的前一个节点和后一个节点,然后将它们连接起来,去除目标节点的引用,最后返回目标节点的元素值。
以上是LinkedList的源码分析,通过了解LinkedList的实现原理,我们可以更好地利用它来实现一些需求。
如下是部分源码截图:
存储结构
LinkedList采用链表的数据结构实现,将每个元素封装成一个Node节点,每个节点都有两个属性:元素值和指向下一个节点的指针。因此,每个节点在内存中都是相互独立的,可以独立增删,设计上也更灵活。
基本操作
Linkedlist提供了一系列基本操作,包括添加元素、删除元素、查找元素、获取元素等。其中较为常见的操作有以下几种:
- add(E e):在LinkedList的末尾添加一个元素。
- addFirst(E e):在LinkedList的开头添加一个元素。
- addLast(E e):在LinkedList的末尾添加一个元素。
- remove():删除LinkedList中的第一个元素。
- remove(Object o):删除LinkedList中指定的元素。
- removeFirst():删除LinkedList中的第一个元素。
- removeLast():删除LinkedList中的最后一个元素。
- size():获取LinkedList的元素数量。
- get(int index):根据下标获取LinkedList中指定的元素。
- set(int index, E element):替换LinkedList中指定下标的元素。
如下是部分源码截图:
应用场景案例
LinkedList的应用场景非常丰富,主要包括以下几种:
- 实现栈和队列:LinkedList可以作为栈和队列的底层数据结构,实现入栈、出栈、入队、出队等功能。
- 缓存:如果需要存储大量的数据,并且需要快速访问最近使用的数据,可以使用LinkedList实现缓存,将最近访问的数据放在LinkedList的头部,当缓存已满时,将最久未使用的数据删除。
- 列表:LinkedList可以用来存储和操作列表数据,如添加、删除和移动元素等。
- 循环链表:LinkedList可以实现循环链表,即最后一个节点指向第一个节点,可以实现循环遍历和处理操作。
优缺点分析
LinkedList的优点如下:
- 可以动态添加、删除元素,在元素数量未知或者动态变化的情况下使用更为灵活。
- 添加、删除元素时,不需要移动其他元素,操作效率较高。
- 可以存储不同类型的元素,具有较高的灵活性。
LinkedList的缺点如下:
- 查找、访问LinkedList中的元素时,需要遍历LinkedList,效率较低。
- 需要额外的内存空间来存储节点的指针信息。
类代码方法介绍
LinkedList类的主要方法如下:
public boolean add(E e); // 添加元素到LinkedList的末尾
public void add(int index, E element);// 添加元素到LinkedList的指定位置
public void addFirst(E e); // 添加元素到LinkedList的开头
public void addLast(E e); // 添加元素到LinkedList的末尾
public void clear(); // 清空LinkedList中的所有元素
public Object clone(); // 复制LinkedList
public boolean contains(Object o); // 判断LinkedList中是否包含指定元素
public E get(int index); // 获取LinkedList中指定位置的元素
public E getFirst(); // 获取LinkedList中的第一个元素
public E getLast(); // 获取LinkedList中的最后一个元素
public int indexOf(Object o); // 获取LinkedList中指定元素的下标
public boolean isEmpty(); // 判断LinkedList是否为空
public Iterator<E> iterator(); // 获取LinkedList的迭代器
public int lastIndexOf(Object o); // 获取LinkedList中指定元素最后一次出现的下标
public ListIterator<E> listIterator();// 获取LinkedList的列表迭代器
public boolean remove(Object o); // 删除LinkedList中指定元素
public E remove(int index); // 删除LinkedList中指定下标的元素
public E removeFirst(); // 删除LinkedList中的第一个元素
public boolean removeFirstOccurrence(Object o);// 删除LinkedList中第一次出现的指定元素
public E removeLast(); // 删除LinkedList中的最后一个元素
public boolean removeLastOccurrence(Object o);// 删除LinkedList中最后一次出现的指定元素
public int size(); // 获取LinkedList中的元素数量
public Object[] toArray(); // 将LinkedList转化为数组
代码分析
LinkedList是Java集合框架中的一种双向链表实现的列表,支持快速的增删改查操作。其常用方法包括:
- add(E e):在列表末尾添加元素,返回是否添加成功。
- add(int index, E element):在指定位置插入元素,返回是否插入成功。
- addFirst(E e):在列表开头插入元素。
- addLast(E e):在列表末尾插入元素。
- clear():清空列表中的所有元素。
- clone():克隆一个新的LinkedList。
- contains(Object o):判断列表中是否包含指定元素。
- get(int index):获取指定位置的元素。
- getFirst():获取列表中的第一个元素。
- getLast():获取列表中的最后一个元素。
- indexOf(Object o):返回指定元素在列表中的首次出现位置的索引,若不存在则返回-1。
- isEmpty():判断列表是否为空。
- iterator():返回一个迭代器,用于遍历列表中的元素。
- lastIndexOf(Object o):返回指定元素在列表中最后一次出现位置的索引,若不存在则返回-1。
- listIterator():返回一个列表迭代器,用于遍历列表中的元素。
- remove(Object o):移除列表中的指定元素,返回是否移除成功。
- remove(int index):移除列表中指定位置的元素,返回被移除的元素。
- removeFirst():移除列表中第一个元素。
- removeFirstOccurrence(Object o):移除列表中第一次出现的指定元素,返回是否移除成功。
- removeLast():移除列表中的最后一个元素。
- removeLastOccurrence(Object o):移除列表中最后一次出现的指定元素,返回是否移除成功。
- size():返回列表中的元素个数。
- toArray():将列表转换为一个数组。
测试用例
测试代码演示
下面给出LinkedList的一个简单测试用例:
package com.demo.javase.day59;import java.util.LinkedList;/*** @Author bug菌* @Date 2023-11-05 23:48*/
public class LinkedListTest {public static void main(String[] args) {LinkedList<String> linkedList = new LinkedList<String>();// 添加元素到LinkedListlinkedList.add("A");linkedList.add("B");linkedList.add("C");// 打印LinkedList中的元素System.out.println(linkedList);// 在LinkedList的开头和末尾添加元素linkedList.addFirst("D");linkedList.addLast("E");// 打印LinkedList中的元素System.out.println(linkedList);// 删除LinkedList中的第一个和最后一个元素linkedList.removeFirst();linkedList.removeLast();// 打印LinkedList中的元素System.out.println(linkedList);// 获取LinkedList中的元素数量int size = linkedList.size();System.out.println("size: " + size);// 根据下标获取LinkedList中指定的元素String element = linkedList.get(1);System.out.println("element: " + element);// 替换LinkedList中指定下标的元素linkedList.set(1, "F");// 打印LinkedList中的元素System.out.println(linkedList);}
}
测试结果
根据如上测试用例,本地测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加更多的测试数据或测试方法,进行熟练学习以此加深理解。
测试代码分析
根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。
这是一个使用Java中的LinkedList类进行操作的示例代码。主要实现了以下功能:
- 创建一个空的LinkedList对象。
- 向LinkedList中添加元素。
- 在LinkedList的开头和末尾添加元素。
- 删除LinkedList中的第一个和最后一个元素。
- 获取LinkedList中的元素数量。
- 根据下标获取LinkedList中指定的元素。
- 替换LinkedList中指定下标的元素。
运行代码后,会输出LinkedList中的元素以及各种操作后的结果。
全文小结
本文对Java中LinkedList的基础概念和操作进行了详细介绍,包括存储结构、基本操作、应用场景案例、优缺点分析以及类代码方法介绍等内容。希望读者可以通过本文全面了解并掌握LinkedList的使用方法,提升在实际开发中的应用能力和水平。
总结
LinkedList是Java中常用的一种集合,可用于实现栈、队列、缓存、列表等场景中。LinkedList采用链式存储结构实现,每个节点都保存了下一个节点的内存地址,因此可以实现动态添加、删除和查找等操作。在使用LinkedList时需要注意
…
好啦,这期的内容就基本接近尾声啦,若你想学习更多,可以参考这篇专栏总结《「滚雪球学Java」教程导航帖》,本专栏致力打造最硬核 Java 零基础系列学习内容,🚀打造全网精品硬核专栏,带你直线超车;欢迎大家订阅持续学习。
附录源码
如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。
☀️建议/推荐你
无论你是计算机专业的学生,还是对编程有兴趣的小伙伴,都建议直接毫无顾忌的学习此专栏「滚雪球学Java」,bug菌郑重承诺,凡是学习此专栏的同学,均能获取到所需的知识和技能,全网最快速入门Java编程,就像滚雪球一样,越滚越大,指数级提升。
最后,如果这篇文章对你有所帮助,帮忙给作者来个一键三连,关注、点赞、收藏,您的支持就是我坚持写作最大的动力。
同时欢迎大家关注公众号:「猿圈奇妙屋」 ,以便学习更多同类型的技术文章,免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板、技术文章Markdown文档等海量资料。
📣关于我
我是bug菌,CSDN | 掘金 | infoQ | 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,华为云 | 阿里云| 腾讯云等社区优质创作者,全网粉丝合计15w+ ;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等海量资料。
相关文章:

LinkedList讲解指南
咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好…...

IP如何异地共享文件?
【天联】 组网由于操作简单、跨平台应用、无网络要求、独创的安全加速方案等原因,被几十万用户广泛应用,解决了各行业客户的远程连接需求。采用穿透技术,简单易用,不需要在硬件设备中端口映射即可实现远程访问。 异地共享文件 在…...

HCIA-Datacom H12-811 题库补充(3/28)
完整题库及答案解析,请直接扫描上方二维码,持续更新中 OSPFv3使用哪个区域号标识骨干区域? A:0 B:3 C:1 D:2 答案:A 解析:AREA 号0就是骨干区域。 STP下游设备通知上游…...
轻量级富文本编辑 Trumbowyg —— 基于 jQuery 插件配置
使用方法👇 首先,添加jQuery到页面<body>位置: <script src"http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script> <script>window.jQuery || document.write(<script src"js/vendor/jquery-1.10.2.min.js&qu…...

那些王道书里的题目-----计算机网络篇
注:仅记录个人认为有启发的题目 p155 34.下列四个地址块中,与地址块 172.16.166.192/26 不重叠,且与172.16.166.192/26聚合后的地址块不会引入多余地址的是() A.172.16.166.192/27 B.172.16.166.128/26 …...
【前端学习——js篇】 10.this指向
具体见:https://github.com/febobo/web-interview 10.this指向 根据不同的使用场合,this有不同的值,主要分为下面几种情况: 默认绑定隐式绑定new绑定显示绑定 ①默认绑定 全局环境中定义person函数,内部使用this关…...
项目搭建之统一返回值
自定义枚举类 Getter public enum ReturnCodeEnum {/*** 操作失败**/RC999("999","操作XXX失败"),/*** 操作成功**/RC200("200","success"),/*** 服务降级**/RC201("201","服务开启降级保护,请稍后再试!"),/*** …...

嵌入式和 Java 走哪条路?
最近看到一个物联网大三学生的疑问,原话如下: 本人普通本科物联网工程专业,开学大三,现在就很迷茫,不打算考研了,准备直接就业,平时一直在实验室参加飞思卡尔智能车比赛,本来是想走嵌…...

C++ 控制语句(一)
一 顺序结构 程序的基本结构有三种: 顺序结构、分支结构、循环结构 大量的实际问题需要通过各种控制流程来解决。 1.1 顺序结构 1.2 简单语句和复合语句 二 循环 2.1 for循环 语句流程图 注意:使用for语句的灵活性 三 while语句 四 do while语句...
mysql 用户管理-权限表
学习了《mysql5.7安装》,就先再了解下用户管理,先了解下权限表。 MySQL是一个多用户数据库,具有功能强大的访问控制系统,可以为不同用户指定允许 的权限。MySQL用户可以分为普通用户和root用户。root 用户是超级管理员,拥有所有权…...

【Postman如何进行接口测试简单详细操作实例】
1、下载Postman postman下载地址:Download Postman | Get Started for Free 2、安装Postman (1)双击下载好的postman-setup.exe文件,进行安装postman工具 (2)安装完成后,在桌面找到并打开postman软件,输入邮箱和密码进行登录&a…...
docker搭建Project Calico环境
Project Calico 是一个开源的网络和网络安全解决方案,专为容器、虚拟机和本地工作负载设计。它提供了高度可扩展的网络层,支持广泛的容器编排平台,如 Kubernetes、Docker Swarm和OpenStack。Calico 的主要特点包括: 支持多层网络策略,包括基于角色的访问控制(RBAC)。提供网…...

pyecharts操作一
pyecharts 是一个用于生成Echarts图表的Python库。Echarts是百度开源的一个数据可视化JS库,可以生成一些非常酷炫的图表。 环境安装 pip install pyecharts 检查版本 import pyecharts print(pyecharts.version) 2.0.3 柱状图绘制 from pyecharts.charts impor…...

『Apisix进阶篇』动态负载均衡:APISIX的实战演练与策略应用
🚀『Apisix系列文章』探索新一代微服务体系下的API管理新范式与最佳实践 【点击此跳转】 📣读完这篇文章里你能收获到 🎯 掌握APISIX中多种负载均衡策略的原理及其适用场景。📈 学习如何通过APISIX的Admin API和Dashboard进行负…...

【开发篇】十一、GC调优的分析工具
文章目录 1、调优的主要指标2、工具一:jstat3、工具二:Visual VM的插件4、工具三:Prometheus Grafana5、生成GC日志6、工具四:GC Viewer7、工具五:GCeasy GC调优,是为了避免因垃圾回收引起程序性能下降&am…...

SpringCloudConfig 使用git搭建配置中心
一 SpringCloudConfig 配置搭建步骤 1.引入 依赖pom文件 引入 spring-cloud-config-server 是因为已经配置了注册中心 <dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</…...
c#基础-引用类型和值类型的区别
在C#中,数据类型分为两类:值类型和引用类型。 值类型:直接存储数据,分配在栈(Stack)上。常见的值类型包括基本数据类型(int, float, double等),结构体(struct),枚举(enum)等。 引用类型:存储数据的引用和对象,分配在托管堆(Heap)上。常见的引用类型包括类(cla…...
面试题-3.20
1、__FILE__表示什么意思? __FILE__:当前文件的完整路径和文件名 __LINE__:当前行 __DIR__:当前文件所在的目录 2、如何获取客户端的IP地址? 通过超全局数组$_SERVER:echo $_SERVER[REMOTE_PORT]; 3、写…...

glibc内存管理ptmalloc - 多线程内存管理
上图 此图着重描述的是子线程,一个heap(由heap_info结构体描述)用完,需要另一个的情况。 子线程内存特点 1. 第一个heap物理内存上从低地址到高地址依次是:heap_infomalloc_state(arena)chunks /* arena.c #0 new_…...

区块链食品溯源案例实现(一)
引言: 食品安全问题一直是社会关注的热点,而食品溯源作为解决食品安全问题的重要手段,其重要性不言而喻。传统的食品溯源系统往往存在数据易被篡改、信息不透明等问题,而区块链技术的引入,为食品溯源带来了革命性的变革…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结: 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析: 实际业务去理解体会统一注…...
Python如何给视频添加音频和字幕
在Python中,给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加,包括必要的代码示例和详细解释。 环境准备 在开始之前,需要安装以下Python库:…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...
深入理解Optional:处理空指针异常
1. 使用Optional处理可能为空的集合 在Java开发中,集合判空是一个常见但容易出错的场景。传统方式虽然可行,但存在一些潜在问题: // 传统判空方式 if (!CollectionUtils.isEmpty(userInfoList)) {for (UserInfo userInfo : userInfoList) {…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...