news 2026/5/12 14:06:10

集合进阶(List集合)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
集合进阶(List集合)

List系列集合

前面我们已经把Collection通用的功能学习完了,接下来我们学习Collection下面的一个子体系List集合。如下图所示:

3.1 List集合的常用方法

List集合是索引的,所以多了一些有索引操作的方法,如下图所示:

接下来,我们用代码演示一下这几个方法的效果

public class ListTest1 { public static void main(String[] args) { // 创建一个ArrayList集合对象(有序、有索引、可以重复) List<String> list = new ArrayList<>(); list.add("蜘蛛精"); list.add("至尊宝"); list.add("至尊宝"); list.add("牛夫人"); System.out.println(list); // [蜘蛛精, 至尊宝, 至尊宝, 牛夫人] ​ // 在某个索引位置插入元素 list.add(2, "紫霞仙子"); System.out.println(list); // [蜘蛛精, 至尊宝, 紫霞仙子, 至尊宝, 牛夫人] ​ // 根据索引删除元素, 返回被删除的元素 System.out.println(list.remove(2)); // 紫霞仙子 System.out.println(list);// [蜘蛛精, 至尊宝, 至尊宝, 牛夫人] ​ // 返回集合中指定位置的元素 System.out.println(list.get(3)); ​ // 修改索引位置处的元素,修改后,会返回原数据 System.out.println(list.set(3, "牛魔王")); // 牛夫人 System.out.println(list); // [蜘蛛精, 至尊宝, 至尊宝, 牛魔王] } }

3.2 List集合的遍历方式

List集合相比于前面的Collection多了一种可以通过索引遍历的方式,所以List集合遍历方式一共有四种:

  • 普通for循环(只因为List有索引)

  • 迭代器

  • 增强for

  • Lambda表达式

public class ListTest2 { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("蜘蛛精"); list.add("至尊宝"); list.add("糖宝宝"); ​ // 1.普通for循环 for(int i = 0; i< list.size(); i++){ //i = 0, 1, 2 String e = list.get(i); System.out.println(e); } ​ System.out.println("--------------"); ​ // 2.增强for遍历 for(String s : list){ System.out.println(s); } ​ System.out.println("--------------"); ​ // 3.迭代器遍历 Iterator<String> it = list.iterator(); while(it.hasNext()){ String s = it.next(); System.out.println(s); } ​ System.out.println("--------------"); ​ // 4.lambda表达式遍历 list.forEach(s -> System.out.println(s)); } }

3.3 ArrayList底层的原理(面试题)

为了让同学们更加透彻的理解ArrayList集合,接下来,学习一下ArrayList集合的底层原理。

ArrayList集合底层(存储、组织数据的方式)是基于数组结构实现的,也就是说当你往集合容器中存储元素时,底层本质上是往数组中存储元素。 特点如下:

我们知道数组的长度是固定的,但是集合的长度是可变的,这是怎么做到的呢?

集合的底层原理如下:数组扩容,并不是在原数组上扩容(原数组是不可以扩容的),底层是创建一个新数组,然后把原数组中的元素全部复制到新数组中去。

3.4 ArrayList的应用场景

应用场景: 1、ArrayList适合: 根据索引查询数据,比如根据随机索引取数据(高效)! 或者数据量不是很大时! 2、ArrayList不适合: 数据量大的,同时又要频繁的进行增删操作!

总结: 1、List系列集合的特点是什么? ArrayList、LinekdList :有序,可重复,有索引。 ​ 2、ArrayList集合的底层是基于什么实现的, 有什么特点呢? 数组 特点: 查询快, 增删慢 3、ArrayList集合适合什么业务场景?不适合什么业务场景? ArrayList适合: 根据索引查询数据,比如根据随机索引取数据(高效)! 或者数据量不是很大时! ArrayList不适合: 数据量大的,同时又要频繁的进行增删操作!

3.5 LinkedList底层原理

学习完ArrayList底层原理之后,接下来我们看一下LinkedList集合的底层原理。

LinkedList底层是链表结构,基于双链表实现的。

链表结构是由一个一个的节点组成,一个节点由数据值、下一个元素的地址组成。如下图所示:

假如,现在要在B节点和D节点中间插入一个元素,只需要把B节点指向D节点的地址断掉,重新指向新的节点地址就可以了。如下图所示:假如,现在想要把D节点删除,只需要让C节点指向E节点的地址,然后把D节点指向E节点的地址断掉。此时D节点就会变成垃圾,会被垃圾回收器清理掉。上面的链表是单向链表,它的方向是从头节点指向尾节点的,只能从左往右查找元素,这样查询效率比较慢;还有一种链表叫做双向链表,不光可以从左往右找,还可以从右往左找。如下图所示:

LinkedList集合是基于双向链表实现了,为什么它会对首尾元素进行增删改查的速度是极快的,因为双向链表是有头结点地址和尾结点地址, 通过头结点地址和尾结点地址可以快速的找到第一个元素

和最后一个元素,那么在头和尾节点进行增删速度肯定是极快的,比如在尾结点后加一个元素,让尾结点指向新加的元素,那么新加的元素就是尾结点,头结点同理可知,如果删除尾结点,尾结点一旦删除倒数第二个就是尾结点,所以说首尾元素进行增删改查的速度是极快的,但是对中间的数据还是需要找到对应节点位置才可以操作。

所以相对于ArrayList新增了一些可以针对头尾进行操作的方法,如下图示所示:

3.6 LinkedList集合的应用场景

刚才我们学习了LinkedList集合,那么LinkedList集合有什么用呢?可以用它来设计栈结构、队列结构。

  • 我们先来认识一下队列结构,队列结构你可以认为是一个上端开口就是入队,下端也开口的管子的形状就是出队。元素从上端入队列,从下端出队列。所以队列的特点就是先进先出,后进后出

入队列可以调用LinkedList集合的addLast方法,出队列可以调用removeFirst()方法.

public class LinkedListTest1 { public static void main(String[] args) { // 创建一个队列:先进先出、后进后出 LinkedList<String> queue = new LinkedList<>(); ​ // 入对列 queue.addLast("第1号人"); queue.addLast("第2号人"); queue.addLast("第3号人"); queue.addLast("第4号人"); System.out.println(queue); ​ // 出队列 System.out.println(queue.removeFirst()); System.out.println(queue.removeFirst()); System.out.println(queue.removeFirst()); System.out.println(queue.removeFirst()); ​ System.out.println(queue); } }

有没有感觉栈结构很像,手枪的子弹夹呀!!第一个压进入的子弹在最底下,最后一个才能打出来,最后一个压进入的子弹在最顶上,第一个打出来。

  • 接下来,我们再用LinkedList集合来模拟一下栈结构的效果。还是先来认识一下栈结构长什么样。栈结构可以看做是一个上端开头,下端闭口的水杯的形状。

    元素永远是上端进,也从上端出,先进入的元素会压在最底下,所以栈结构的特点是先进后出,后进先出

接着,我们就用LinkedList来模拟下栈结构,代码如下:

public class LinkedListTest2 { public static void main(String[] args) { //创建一个栈对象 LinkedList<String> stack = new LinkedList<>(); ​ // addFirst() /*stack.addFirst("第1颗子弹"); stack.addFirst("第2颗子弹"); stack.addFirst("第3颗子弹"); stack.addFirst("第4颗子弹");*/ ​ // 压栈(push) 等价于 addFirst() stack.push("第1颗子弹"); stack.push("第2颗子弹"); stack.push("第3颗子弹"); stack.push("第4颗子弹"); System.out.println(stack); //[第4颗子弹, 第3颗子弹, 第2颗子弹,第1颗子弹] ​ // removeFirst() /*System.out.println(stack.removeFirst()); System.out.println(stack.removeFirst()); System.out.println(stack.removeFirst()); System.out.println(stack.removeFirst());*/ ​ // 弹栈(pop) 等价于 removeFirst() System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); System.out.println(stack.pop()); ​ //弹栈完了,集合中就没有元素了 System.out.println(stack); //[] } }
总结: LinkedList集合的底层原理 基于双链表实现的。 特点:查询慢,增删相对较快,但对首尾元素进行增删改查的速度是极快的。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/12 14:05:13

如何5分钟搞定Mac Boot Camp驱动部署:Brigadier终极指南

如何5分钟搞定Mac Boot Camp驱动部署&#xff1a;Brigadier终极指南 【免费下载链接】brigadier Fetch and install Boot Camp ESDs with ease. 项目地址: https://gitcode.com/gh_mirrors/bri/brigadier 还在为Mac电脑安装Windows驱动而头疼吗&#xff1f;&#x1f914…

作者头像 李华
网站建设 2026/5/12 14:04:03

Claude Code与Cursor CLI集成:AI辅助编程工作流优化实践

1. 项目概述&#xff1a;Claude Code与Cursor CLI的桥梁如果你和我一样&#xff0c;日常开发中同时使用Claude Code和Cursor&#xff0c;并且对Composer 2的执行速度印象深刻&#xff0c;那么你很可能也面临过这样的困境&#xff1a;Claude Code在规划、分析和代码审查方面表现…

作者头像 李华
网站建设 2026/5/12 14:03:53

dataworkers-claw-community:构建可协作、工程化的数据采集平台

1. 项目概述与核心价值 最近在数据采集和自动化处理这个圈子里&#xff0c;一个名为 dataworkers-claw-community 的项目开始被频繁提及。乍一看这个名字&#xff0c;你可能会觉得它又是一个普通的爬虫框架或者工具集。但如果你像我一样&#xff0c;在这个领域摸爬滚打了十几…

作者头像 李华
网站建设 2026/5/12 14:03:34

Engram:基于知识图谱与向量搜索的AI编程决策记忆系统

1. 项目概述&#xff1a;为开发者打造的AI决策记忆系统 如果你和我一样&#xff0c;每天都在用Claude Code、Cursor或者VS Code配合AI助手写代码&#xff0c;那你肯定也遇到过这个烦人的问题&#xff1a;每次关掉一个AI会话&#xff0c;那些花了半小时讨论出来的技术决策、被否…

作者头像 李华
网站建设 2026/5/12 14:02:52

从玩具小车到写字机:用51单片机和A4988玩转步进电机的5个创意项目

从玩具小车到写字机&#xff1a;用51单片机和A4988玩转步进电机的5个创意项目 当你第一次拿到A4988驱动模块和步进电机时&#xff0c;可能会觉得这不过是个能转动的零件而已。但在这个创客时代&#xff0c;这些基础元件却能化身成令人惊叹的创意作品。51单片机作为经典的入门级…

作者头像 李华
网站建设 2026/5/12 13:56:38

告别重复操作!用Verdi的TCL脚本和Session功能打造你的专属自动化工作流

告别重复操作&#xff01;用Verdi的TCL脚本和Session功能打造你的专属自动化工作流 在数字芯片验证的日常工作中&#xff0c;工程师们常常需要反复执行相同的GUI操作&#xff1a;加载设计文件、添加特定信号到波形窗口、调整显示参数、保存调试视图......这些重复劳动不仅消耗宝…

作者头像 李华