Java [ 基础 ] 数组、ArrayList和LinkedList✨

news2024/11/17 16:16:15

目录

✨探索Java基础   数组、ArrayList和LinkedList✨

一、总体介绍

二、分别介绍

1. 数组(Array)

2. ArrayList

3. LinkedList

三、区别总结

四、常见面试题

如何选择使用数组、ArrayList和LinkedList?

如何实现线程安全的ArrayList?

解释ArrayList的底层实现及其扩容机制

LinkedList的插入和删除操作为什么比ArrayList快?

如何在不使用额外空间的情况下,反转一个链表?


✨探索Java基础   数组、ArrayList和LinkedList✨

在Java编程中,数据结构是非常重要的基础知识。在众多数据结构中,数组(Array)、ArrayList和LinkedList是最常用的三种。


一、总体介绍

数组(Array)ArrayListLinkedList都是用于存储数据的容器,但它们在存储机制、性能、使用场景等方面有着显著的区别。了解这些区别能帮助我们在不同场景下选择最适合的数据结构。

二、分别介绍
1. 数组(Array)

数组是最基本的数据结构之一,用于存储固定大小的同类型元素的集合。每个元素都可以通过其索引进行访问。

特点:

  • 固定大小:数组一旦创建,大小不能改变。
  • 索引访问:数组的每个元素通过索引访问,时间复杂度为O(1)。
  • 内存连续:数组在内存中是连续分配的,这使得数组访问速度非常快,但增加和删除操作会比较复杂。

示例代码:

int[] numbers = new int[5]; // 创建一个长度为5的整数数组
numbers[0] = 10; // 给数组的第一个元素赋值
System.out.println(numbers[0]); // 输出第一个元素
2. ArrayList

ArrayList是Java集合框架的一部分,实际上是一个动态数组。它可以自动调整自身的大小以适应添加和删除的操作。

特点:

  • 动态大小:ArrayList可以根据需要自动调整大小。
  • 索引访问:与数组类似,ArrayList通过索引访问元素,时间复杂度为O(1)。
  • 非线程安全:默认情况下,ArrayList是非线程安全的。

示例代码:

ArrayList<Integer> list = new ArrayList<>();
list.add(10); // 向ArrayList中添加元素
list.add(20);
System.out.println(list.get(0)); // 通过索引访问第一个元素
3. LinkedList

LinkedList是基于链表的数据结构,它可以存储任何类型的对象,并允许高效的插入和删除操作。

特点:

  • 双向链表:LinkedList在内部实现是双向链表,每个节点包含对前一个和后一个节点的引用。
  • 插入和删除操作快:插入和删除操作时间复杂度为O(1)。
  • 索引访问慢:由于链表需要从头遍历到目标节点,索引访问时间复杂度为O(n)。

示例代码:

LinkedList<Integer> linkedList = new LinkedList<>();
linkedList.add(10); // 向LinkedList中添加元素
linkedList.add(20);
System.out.println(linkedList.get(0)); // 通过索引访问第一个元素

三、区别总结
  1. 存储方式

    • 数组:连续内存存储。
    • ArrayList:动态数组,内存不连续。
    • LinkedList:双向链表,内存不连续。
  2. 大小

    • 数组:固定大小。
    • ArrayList:动态调整大小。
    • LinkedList:动态调整大小。
  3. 性能

    • 数组:访问快,插入删除慢。
    • ArrayList:访问快,插入删除相对慢。
    • LinkedList:访问慢,插入删除快。
  4. 线程安全

    • 数组:线程安全(需要手动实现)。
    • ArrayList:非线程安全。
    • LinkedList:非线程安全。
四、常见面试题
  1. 如何选择使用数组、ArrayList和LinkedList?
  2. 如何实现线程安全的ArrayList?
  3. 解释ArrayList的底层实现及其扩容机制。
  4. LinkedList的插入和删除操作为什么比ArrayList快?
  5. 如何在不使用额外空间的情况下,反转一个链表?

如何选择使用数组、ArrayList和LinkedList?

选择合适的数据结构取决于具体的使用场景和需求:

  1. 数组(Array)

    • 适用场景:数据量固定且已知;需要频繁随机访问元素。
    • 优点:访问速度快(O(1));内存连续,缓存友好。
    • 缺点:大小固定;插入和删除操作效率低(需要移动元素)。
  2. ArrayList

    • 适用场景:需要动态调整大小;需要频繁随机访问元素。
    • 优点:大小可动态调整;随机访问速度快(O(1))。
    • 缺点:插入和删除操作相对较慢(O(n));扩容时可能会影响性能。
  3. LinkedList

    • 适用场景:需要频繁插入和删除操作;数据量变化频繁且未知。
    • 优点:插入和删除操作快(O(1));不需要预分配固定大小。
    • 缺点:随机访问速度慢(O(n));额外的内存开销(存储节点的指针)。

如何实现线程安全的ArrayList?

默认情况下,ArrayList是非线程安全的。如果需要在多线程环境中使用ArrayList,可以通过以下几种方式实现线程安全:

  1. 使用Collections.synchronizedList

List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
  1. 使用CopyOnWriteArrayList(适用于读操作多,写操作少的场景)

List<Integer> cowList = new CopyOnWriteArrayList<>();
  1. 手动同步: 在操作ArrayList时,手动加锁:

List<Integer> list = new ArrayList<>();
synchronized (list) {
    list.add(10);
}

解释ArrayList的底层实现及其扩容机制

底层实现: ArrayList是基于数组实现的动态数组。内部维护一个数组elementData来存储元素,当数组容量不足时,会自动扩容。

扩容机制

  1. 初始容量:当创建ArrayList时,如果不指定初始容量,默认初始容量为10
  2. 扩容条件:当添加元素使得ArrayList的当前容量不够时,会触发扩容。
  3. 扩容策略:新的容量为旧容量的1.5倍,即newCapacity = oldCapacity + (oldCapacity >> 1)
  4. 扩容过程:创建一个更大的新数组,将旧数组中的元素复制到新数组中,然后用新数组替换旧数组。

LinkedList的插入和删除操作为什么比ArrayList快?

LinkedList的插入和删除操作时间复杂度为O(1),主要原因是其链表结构:

  1. 链表结构:LinkedList是基于双向链表实现的,每个节点包含前一个和后一个节点的引用。
  2. 插入操作:插入一个元素只需要调整相邻节点的引用,不需要移动其他元素。
  3. 删除操作:删除一个元素同样只需要调整相邻节点的引用,不需要移动其他元素。

相比之下,ArrayList的插入和删除操作需要移动大量元素,时间复杂度为O(n)。

如何在不使用额外空间的情况下,反转一个链表?

对应LeetCode  题目  LCR 024. 反转链表icon-default.png?t=N7T8https://leetcode.cn/problems/UHnkqh/description/

对应的题解:

力扣第24题 两两交换链表中的节点 c++精讲 。_力扣24题-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/jgk666666/article/details/133253909?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171998475016800225528659%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=171998475016800225528659&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-133253909-null-null.nonecase&utm_term=%E9%93%BE%E8%A1%A8&spm=1018.2226.3001.4450

反转链表可以通过就地反转的方法实现,不需要使用额外的空间。下面是单链表反转的示例代码:

此方法通过三个指针prevcurrentnext逐步反转链表的指针,时间复杂度为O(n),空间复杂度为O(1)。

通过以上介绍,我们详细地了解了数组、ArrayList和LinkedList的基本概念、特点及其区别。在实际开发中,根据具体需求选择合适的数据结构能够显著提升程序的性能和可维护性。

觉得有用的话可以点点赞 (*/ω\*),支持一下。

如果愿意的话关注一下。会对你有更多的帮助。

每天都会不定时更新哦  >人<  。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1891857.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

stm32cubeide的undefined reference难解之谜

stm32cubeide 的 undefined reference 难解之谜 今天使用意法半导体公司的STM32CubeIDE 1.15.0编码器 遇到了一个熟悉&#xff0c;却令我绞尽脑汁的问题 这个问题大家应该都挺常见的 有以下几种要注意的地方 1、路径是否包含 2、函数是否在C文件定义 3、函数是否在头文件中定…

美国拟立法评估:极端网络攻击下关基设施能否切换手动操作

文章目录 前言一、评估关基设施快速切换手动操作的可行性1、评估需包括如下内容:2、政策保障关键基础设施运行二、保障关基设施安全迫不容缓前言 随着来自俄罗斯、伊朗和朝鲜等敌对国家以及国家关联团体的威胁不断增加,网络攻击对电网、水务系统和管道等关键基础设施的潜在破…

Python绘制动态树形:实现分形树动画

文章目录 引言准备工作前置条件 代码实现与解析导入必要的库初始化Turtle绘制分形树函数动态绘制函数主函数 完整代码 引言 分形树是一种通过递归生成的美丽图案&#xff0c;在数学和计算机图形学中有着重要的地位。在这篇博客中&#xff0c;我们将使用Python创建一个动态的分…

【C语言】union 关键字

在C语言中&#xff0c;union关键字用于定义联合体。联合体是一种特殊的数据结构&#xff0c;它允许不同的数据类型共享同一段内存。所有联合体成员共享同一个内存位置&#xff0c;因此联合体的大小取决于其最大成员的大小。 定义和使用联合体 基本定义 定义一个联合体类型时…

【NOI-题解】1372. 活动选择1456. 淘淘捡西瓜1485. 接水问题

文章目录 一、前言二、问题问题&#xff1a;1372. 活动选择问题&#xff1a;1456. 淘淘捡西瓜问题&#xff1a;1485. 接水问题 三、感谢 一、前言 本章节主要对贪心问题进行讲解&#xff0c;包括《1372. 活动选择》《1456. 淘淘捡西瓜》《1485. 接水问题》题目。 二、问题 问…

Pandas函数详解:案例解析(第25天)

系列文章目录 Pandas函数详解排序函数聚合函数缺失值处理日期函数 文章目录 系列文章目录前言1 索引和列名操作1.1 查看索引和列名1.2 修改索引和列名 2 常用计算函数2.1 排序函数2.2 聚合函数2.3 练习 3 缺失值处理3.1 缺失值概念3.2 加载包含缺失值数据3.3 查看缺失值3.4 缺失…

无人机集群协同搜索研究综述

源自&#xff1a;指挥控制与仿真 作者&#xff1a;刘圣洋, 宋婷, 冯浩龙, 孙玥, 韩飞 注&#xff1a;若出现无法显示完全的情况&#xff0c;可 V 搜索“人工智能技术与咨询”查看完整文章 摘要 无人机集群协同区域搜索能够有效地获取任务区域地面信息,降低环境不确定度。基…

【操作系统】操作系统运行环境——处理器的运行模式

处理器的运行模式 导读一、内核程序和应用程序二、特权指令与非特权指令三、用户态与核心态四、内核4.1 时钟管理4.2 中断机制4.3 原语4.4 系统控制的数据结构及处理 结语 导读 大家好&#xff0c;很高兴又和大家见面啦&#xff01;&#xff01;&#xff01; 在上一篇内容中我…

高校教师教学质量评估系统-计算机毕业设计源码03344

摘要 在高等教育中&#xff0c;教学质量是培养优秀人才的关键。为了提高教学质量&#xff0c;高校需要建立一套科学、有效的教师教学质量评估系统。本研究采用 SSM技术框架&#xff0c;旨在开发一款高校教师教学质量评估系统。 SSM框架作为一种成熟的Java开发框架&#xff0c;具…

echarts--Tree的label上添加图片

使用echarts的rich富文本&#xff0c;配合lable的formatter去实现 主要代码&#xff1a;label里 rich: {img1: {backgroundColor: {image: Cloudy,},height: 40}},formatter: function (param) {var res "";res {img1|} param.name;return res;}, 如果想要哪一节…

基于贝叶斯优化的卷积神经网络-循环神经网络混合模型的的模拟股票时间序列预测(MATLAB R2021B)

将机器学习和深度学习方法运用到股市分析中, 不仅具有一定的理论价值, 也具有一定的实践价值。从理论价值上讲, 中国的量化投资技术&#xff08;投资观念、方法与决策等&#xff09;还不够成熟, 尚处在起步阶段, 能够将量化投资技术运用到投资决策中的公司寥寥无几。目前, 国内…

程序员学CFA——经济学(五)

经济学&#xff08;五&#xff09; 货币政策与财政政策基本术语货币政策货币货币的功能货币的定义货币的创造过程货币的供给和需求费雪效应 中央银行中央银行的职能中央银行的目标与通货膨胀的成本中央银行的有效性 货币政策工具货币传导机制货币政策的目标与形式货币政策的目标…

AIGC时代算法工程师的面试秘籍(2024.6.10-6.23第十六式) |【三年面试五年模拟】

写在前面 【三年面试五年模拟】旨在整理&挖掘AI算法工程师在实习/校招/社招时所需的干货知识点与面试方法&#xff0c;力求让读者在获得心仪offer的同时&#xff0c;增强技术基本面。也欢迎大家提出宝贵的优化建议&#xff0c;一起交流学习&#x1f4aa; 欢迎大家关注Rocky…

还以网站建设为主营?赶紧转!除非你的网站做比他们还漂亮

案例一&#xff1a;某上市公司2019年找A公司做了一个官网&#xff0c;网站做了三年多&#xff0c;到现在没有上线&#xff0c;该公司业务没受任何影响&#xff0c;一直蒸蒸高日上。案例二&#xff1a;我公司也有自己官网&#xff0c;这么多年页面啥流量&#xff0c;一样不影响我…

001:开源交易系统开发实战开篇

本专栏采用融入【主力思维】的方法学&#xff0c;包含数据抓取、特征模型开发、历史验证回归测试、每日动态风险评估管理等技术&#xff0c;较大的增强股票投资胜率&#xff0c;让IT开发者拥有一套实用的属于自己思路的专用交易软件。 先简要介绍下系统运行的成果和项目架构&a…

这玩意终于有免费的了———Navicat Premium Lite

免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 免费啦&#xff01;&#xff01;&#xff01;X&#xff01;&#xff01;&#xff01; 去下载吧&…

uniapp应用如何实现传感器数据采集和分析

UniApp是一种跨平台的应用开发框架&#xff0c;它支持在同一份代码中同时开发iOS、Android、H5等多个平台的应用。在UniApp中实现传感器数据采集和分析的过程可以分为以下几个步骤&#xff1a; 引入相关插件或库 UniApp通过插件或库的形式扩展功能。对于传感器数据采集和分析&…

无人机对地面运动目标定位---获取目标的移动方向和速度

目录 一、引子 我们利用单目无人机通过等时间间隔拍照的形式对地面某移动目标进行定位&#xff0c;当前&#xff0c;我们已经获得了每张相片上该目标的三维坐标&#xff0c;并且知道该无人机在飞行过程中拍照的时间间隔&#xff0c;那么我们就可以通过一定的计算&#xff0c;得…

Docker学习笔记(一)概念理解

一、什么是docker容器 Docker容器是一种轻量级、可移植的软件封装技术&#xff0c;它允许开发者将应用程序及其依赖、配置文件、运行环境等打包到一个独立的、自包含的执行单元中。容器与虚拟机相似&#xff0c;都提供了隔离的运行环境&#xff0c;但容器更加轻量级&#xff0c…

职业本科扩容:教育改革的新篇章与挑战

高考结束后&#xff0c;李文莉同学并没有如释重负的感觉&#xff0c;因为她正在为选学校、选专业而纠结。幸运的是&#xff0c;今年我国职业本科院校又增加了十多所&#xff0c;这对学习成绩稍差、但动手能力较强的她来说&#xff0c;无疑是个好消息。这几天&#xff0c;她已将…