java ArrayList与LinkedList比较

为了详细说明ArrayList与LinkedList的特性和使用方法,下面我将分别展示如何使用这两个集合类,并通过简单的示例代码来体现它们的特点。

 

### 1. ArrayList 示例

 

```java

import java.util.ArrayList;

import java.util.List;

 

public class ArrayListExample {

    public static void main(String[] args) {

        // 创建ArrayList实例

        List<String> arrayList = new ArrayList<>();

 

        // 添加元素

        arrayList.add("Apple");

        arrayList.add("Banana");

        arrayList.add("Cherry");

 

        // 随机访问(通过索引)

        System.out.println("Element at index 1: " + arrayList.get(1)); // 快速访问

 

        // 在特定位置插入元素(效率较低)

        arrayList.add(1, "Blueberry");

 

        // 删除元素

        arrayList.remove("Banana"); // 按值删除

        arrayList.remove(2); // 按索引删除

 

        // 打印ArrayList

        System.out.println("ArrayList: " + arrayList);

    }

}

```

 

### 2. LinkedList 示例

 

```java

import java.util.LinkedList;

import java.util.List;

 

public class LinkedListExample {

    public static void main(String[] args) {

        // 创建LinkedList实例

        List<String> linkedList = new LinkedList<>();

 

        // 添加元素

        linkedList.add("Apple");

        linkedList.add("Banana");

        linkedList.addLast("Cherry"); // 特定方法添加到末尾

 

        // 随机访问(较慢)

        System.out.println("Element at index 1: " + linkedList.get(1));

 

        // 在头部插入元素(高效)

        linkedList.addFirst("Strawberry");

 

        // 删除元素

        linkedList.removeFirst(); // 高效地移除头部元素

        linkedList.remove(new String("Banana")); // 按值删除

 

        // 打印LinkedList

        System.out.println("LinkedList: " + linkedList);

    }

}

```

 

### 解析

 

- **ArrayList示例**展示了如何创建ArrayList对象、添加元素、通过索引快速访问元素、在特定位置插入和删除元素。通过索引访问和修改体现了ArrayList的优势,而插入和删除操作(特别是中间插入)则相对低效,因为可能需要移动后续元素。

 

- **LinkedList示例**同样展示了创建、添加、访问和删除元素的基本操作,但重点在于利用LinkedList特有的`addFirst`和`removeFirst`方法高效地在列表头部进行操作。同时,通过索引访问元素(如`get(1)`)相对较慢,因为需要从头节点开始遍历链表。

 

这些示例代码直观地展示了ArrayList和LinkedList的核心特性和使用方法,帮助您在实际编程中更好地选择和应用这两种数据结构。

当然,为了进一步深入理解ArrayList与LinkedList的差异,接下来我们将通过一些进阶示例,探讨它们在迭代、内存占用以及转换方面的表现。

 

### 3. 迭代性能比较

 

尽管ArrayList和LinkedList都实现了Iterable接口,可以使用增强for循环或迭代器进行遍历,但由于它们内部结构的不同,遍历效率也有所区别。

 

```java

import java.util.Iterator;

 

public class IterationPerformance {

    public static void iterateArrayList(ArrayList<String> arrayList) {

        long startTime = System.nanoTime();

        for (String item : arrayList) {

            // 遍历操作

        }

        long endTime = System.nanoTime();

        System.out.println("ArrayList iteration time: " + (endTime - startTime) + " ns");

    }

 

    public static void iterateLinkedList(LinkedList<String> linkedList) {

        long startTime = System.nanoTime();

        for (String item : linkedList) {

            // 遍历操作

        }

        long endTime = System.nanoTime();

        System.out.println("LinkedList iteration time: " + (endTime - startTime) + " ns");

    }

 

    public static void main(String[] args) {

        ArrayList<String> arrayList = new ArrayList<>();

        LinkedList<String> linkedList = new LinkedList<>();

 

        // 填充数据

        for (int i = 0; i < 10000; i++) {

            arrayList.add(String.valueOf(i));

            linkedList.add(String.valueOf(i));

        }

 

        iterateArrayList(arrayList);

        iterateLinkedList(linkedList);

    }

}

```

这段代码通过计时比较了遍历一个有10000个元素的ArrayList和LinkedList所需的时间。理论上,由于ArrayList的元素在内存中是连续存储的,现代CPU的高速缓存友好性可能导致其遍历速度略快于LinkedList,后者在遍历时可能需要更多的内存跳跃。

 

### 4. 内存占用分析

 

虽然直接通过代码难以直观展现内存占用情况,但可以通过理论分析来理解两者在内存使用上的差异:

 

- **ArrayList**不仅存储元素本身,还需要额外的空间来记录数组的长度和当前容量。此外,数组通常会有一定的容量冗余以备扩容,这可能导致ArrayList在元素数量较少时有较高的内存开销。

  

- **LinkedList**每个节点包含元素及两个引用(指向前一个和后一个节点),因此每个元素比ArrayList多出两个引用的内存消耗。但在元素数量较少时,LinkedList可能因不需要预留大量未使用的空间而显得更“经济”。

 

### 5. ArrayList与LinkedList转换

 

有时,根据操作需求的变化,你可能需要在ArrayList和LinkedList之间转换。Java提供了直接的构造函数来进行这种转换。

 

```java

public class ConvertCollections {

    public static void main(String[] args) {

        // 创建一个ArrayList

        ArrayList<String> arrayList = new ArrayList<>(Arrays.asList("A", "B", "C"));

 

        // 将ArrayList转换为LinkedList

        LinkedList<String> linkedList = new LinkedList<>(arrayList);

 

        // 反向转换

        ArrayList<String> convertedArrayList = new ArrayList<>(linkedList);

        

        System.out.println("Converted ArrayList: " + convertedArrayList);

        System.out.println("Converted LinkedList: " + linkedList);

    }

}

```

 

这段代码演示了如何通过构造函数直接将ArrayList转换为LinkedList,反之亦然。需要注意的是,转换操作会创建新的集合实例,原集合保持不变。

 

通过这些示例和分析,您可以更全面地掌握ArrayList与LinkedList的使用场景和性能特点,从而在实际开发中做出更加明智的选择。

### Java中的集合框架:深入探索ArrayList与LinkedList

在Java编程的世界里,集合框架无处不在,它为开发者提供了强大的数据结构和算法支持。本文将带您深入探讨Java集合框架中两个极其重要的实现——ArrayList和LinkedList,理解它们的内部工作原理、性能特点及适用场景,从而在实际开发中做出更加合适的选择。

#### 1. Java集合框架简介

Java集合框架位于`java.util`包下,是一个预构建的数据结构库,旨在提供高效的操作集合(如列表、集、映射等)的接口和实现。它主要包括三大接口:List、Set和Map,以及众多的具体实现类,如ArrayList、LinkedList、HashSet、HashMap等。

#### 2. ArrayList:动态数组的威力

**定义与特点:**
ArrayList是List接口的一个实现,底层使用可变大小的数组来存储元素。这意味着它提供了基于索引的快速访问(时间复杂度为O(1)),但插入和删除操作(尤其是列表中间的操作)可能较慢,因为可能需要移动后续的元素以保持连续性。

**优点:**
- **随机访问快**:由于使用数组存储,通过索引访问元素非常迅速。
- **自动扩容**:当数组容量不足以容纳新元素时,ArrayList会自动增加其容量,避免了频繁的手动管理内存。

**缺点:**
- **插入和删除效率低**:特别是在列表中间进行插入或删除时,需要移动大量元素。
- **线程不安全**:ArrayList不是线程安全的,多线程环境下需手动同步或使用`Vector`(线程安全的ArrayList旧版本)。

#### 3. LinkedList:链表的灵活性

**定义与特点:**
LinkedList也是List接口的实现,但与ArrayList不同,它使用双向链表作为基础数据结构。每个节点包含元素本身及其前后节点的引用,这使得在列表的任何位置添加或删除元素都非常高效。

**优点:**
- **高效的插入和删除**:在列表的开头或结尾添加/删除元素的时间复杂度为O(1),在列表中间操作虽然仍为O(n),但相比ArrayList,它不需要移动元素,只需改变引用即可。
- **额外功能**:由于链表的特性,LinkedList还实现了Deque接口,可以作为栈、队列或双端队列使用。

**缺点:**
- **随机访问慢**:由于需要从头节点开始遍历链表到达指定位置,因此通过索引访问元素的效率较低(时间复杂度为O(n))。
- **空间开销**:每个节点除了存储元素外,还需额外的空间存储前后节点的引用。

#### 4. 应用场景对比

- **ArrayList**适合于当您主要需要快速随机访问元素,且集合大小相对稳定,不频繁进行插入和删除操作的场景。
- **LinkedList**则更适合频繁进行插入和删除操作,特别是需要在列表两端高效执行这些操作,而对随机访问速度要求不高的场景。

#### 5. 总结

ArrayList和LinkedList各有千秋,选择哪个应根据具体的应用场景和需求来决定。理解它们的内部机制和性能特征,能够帮助我们更有效地利用Java集合框架,提升代码的性能和维护性。在实际开发中,合理选择数据结构是优化程序性能的关键步骤之一。希望本文能为您在Java集合框架的探索之旅上点亮一盏明灯。

 

 

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

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

相关文章

自定义springboot启动环境

FROM openjdk:8-jre-alpine #镜像的制作人 LABEL MAINTAINER723557599qq.com ##定义环境变量RUN mkdir -p /opt/server/ ADD target/ujoined-boot-remote-api-0.0.1-SNAPSHOT.jar /opt/server/app.jar RUN #bash -c touch /opt/server/app.jar #设置环境变量&#xff08;程序运…

产品推荐 | 基于 Zynq UltraScale+ RFSoC 的iW-RainboW-G42M 核心板

01 产品概述 Xilinx Zynq UltraScale基于RFSoC的系统模块采用带有FFVF1760封装的Zynq ScaleRFSoC ZU49/ZU39/ZU29设备。RFSoC支持高达1.3GHz的Quad Cortex A53和高达533MHz的Dual Cortex R5F。SOM支持高达16通道的射频ADC2.5Gsps和16通道的RF DAC10Gsps&#xff0c;所有这些都…

使用nvm安装node.js过程

今天Jade尝试安装nvm&#xff0c;并使用命令安装node.js但是碰到了一些问题&#xff0c;在此作为学习记录分享出来。希望可以留下深刻的印象&#xff1a; 1、概念了解 nvm----- (Node.js version manager)是一个命令行应用&#xff0c;可以协助您快速地 更新、安装、使用、卸载…

鲁大师4月新机性能/流畅/AI/久用榜:骁龙中端双子星表现亮眼,接下来应该是中端机的主场

时间来到5月份&#xff0c;伴随着中考、高考以及暑假将至&#xff0c;以学生家庭为主力的暑期换机潮即将拉开序幕。同时&#xff0c;恰逢骁龙新中端芯片骁龙8s Gen3和7 Gen3的发布&#xff0c;一大批在性能上极具竞争力的中端机型也已经跃跃欲试&#xff0c;为这次的换机潮开始…

net7部署经历

1、linux安装dotnet命令&#xff1a; sudo yum install dotnet-sdk-7.0 或者直接在商店里安装 2、配置反向代理 127.0.0.1:5000》localhost 访问后报错 原因&#xff1a;数据表驼峰名&#xff0c; 在windows的数据表不区分大小写&#xff0c;但是在linux里面是默认区分的&…

java 已知当前时间 如何快速的得出近30天每天的时间

1、使用 Java 中的 LocalDate 类 import java.time.LocalDate; import java.time.format.DateTimeFormatter;public class Main {public static void main(String[] args) {// 获取当前日期LocalDate currentDate LocalDate.now();// 创建日期格式化器DateTimeFormatter form…

C++ | Leetcode C++题解之第75题颜色分类

题目&#xff1a; 题解&#xff1a; class Solution { public:void sortColors(vector<int>& nums) {int n nums.size();int p0 0, p2 n - 1;for (int i 0; i < p2; i) {while (i < p2 && nums[i] 2) {swap(nums[i], nums[p2]);--p2;}if (nums[i…

ESD静电问题 | 手持摄像头整改

【转自微信公众号&#xff1a;柯普伦科技】

Java八股文系列之四(JVM)

什么是Java虚拟机&#xff1f;为什么Java被称作是“平台无关的编程语言”&#xff1f; Java虚拟机是一个可以执行Java字节码的虚拟机进程。 Java 实现跨平台的主要原因在于它的编译和执行方式。Java 程序首先被编译成中间代码&#xff08;bytecode&#xff09;&#xff0c;然…

Android 查看CUP占用率

查看每个进程CUP占用率的几种方式,由于自己充电界面老是导致整机温度过高&#xff0c;后面发现自己的线程一直在跑&#xff0c;相当于死循环&#xff0c;后面加上sleep才得以改善&#xff1b;先看看几种查询方式吧。 1、adb shell top 2、adb shell busybox top 3、adb shell …

Linux 基础命令、性能监控

一、Linux 基础命令 grep&#xff1a;在文件中执行关键词搜索&#xff0c;并显示匹配的结果。 -c 仅显示找到的行数 -i 忽略大小写 -n 显示行号 -v 反向选择: 仅列出没有关键词的行 (invert) -r 递归搜索文件目录 -C n 打印匹配行的前后 n 行grep login user.cpp # 在…

Android OpenMAX(六)OMXStore

在前面两节的学习中我们知道了OMX Core是用来管理(查询/创建/销毁)Android平台上的硬件编解码组件的。这一节我们再向上一层,Android平台除了提供有硬件编解码组件支持,还内置了一些软件编解码组件,为了统一管理所有(软/硬)编解码组件,Android在OMX Core之上又抽象了一…

【p2】求表达式的逆波兰式

规则 遇到字母直接写到答案中遇到符号&#xff0c;加入栈中遇到成对括号&#xff0c;出栈新加入的符号优先级要高于原栈顶优先级&#xff0c;否则栈中元素先出栈 注意事项 答案里面是去除了括号的所有的元素扫描完之后&#xff0c;要把辅助的栈里面的所有符号&#xff0c;按…

副产物三氟甲烷综合利用技术路线多 行业发展受到国家政策支持

副产物三氟甲烷综合利用技术路线多 行业发展受到国家政策支持 氟化工行业生产过程中的副产物内包括三氟甲烷&#xff0c;直接排放进入自然界会污染大气&#xff0c;且会造成资源浪费。副产物三氟甲烷综合利用&#xff0c;是以工业副产物三氟甲烷为原料制备其他化学品的过程&…

Pytorch入门—Tensors张量的学习

Tensors张量的学习 张量是一种特殊的数据结构&#xff0c;与数组和矩阵非常相似。在PyTorch中&#xff0c;我们使用张量来编码模型的输入和输出&#xff0c;以及模型的参数。 张量类似于NumPy的ndarrays&#xff0c;只是张量可以在GPU或其他硬件加速器上运行。事实上&#xf…

深入解析:匿名内部类与Lambda表达式的高级应用

在Java开发中&#xff0c;匿名内部类和Lambda表达式不仅仅是简化代码的工具&#xff0c;它们还有许多高级应用和技巧&#xff0c;可以帮助开发人员更加灵活地处理各种场景。在本节中&#xff0c;我们将深入探讨这些高级用法&#xff0c;以及如何充分发挥它们的潜力。 1. 匿名内…

echarts双Y轴,并实现图例等

一个Y轴时yAxis为对象 yAxis: {type: value,name: 占比(%) },两个Y轴时yAxis为数组 yAxis: [{ // 左侧的type: value,name: 占比(%),nameTextStyle: {padding: [0, 0, 10, -50]},min: 0,max: 100,splitNumber: this.splitNumber, // 设置坐标轴的分割段数interval: 20, // 标轴…

Python | Leetcode Python题解之第69题x的平方根

题目&#xff1a; 题解&#xff1a; class Solution:def mySqrt(self, x: int) -> int:if x 0:return 0C, x0 float(x), float(x)while True:xi 0.5 * (x0 C / x0)if abs(x0 - xi) < 1e-7:breakx0 xireturn int(x0)

Segmentation fault (core dumped)排查

先泼盆冷水&#xff0c;这个问题比较棘手&#xff0c;有的能通过重装opencv相关包修复&#xff0c;有的可能还是直接换一个没问题的环境比较快…… 我最后是没有解决的&#xff0c;折腾了几个小时后&#xff0c;还是听同事的话&#xff0c;把docker镜像重启了&#xff0c;幸好…

数字孪生与虚拟现实结合

在飞速发展的科技世界中&#xff0c;数字孪生与虚拟现实&#xff08;VR&#xff09;的融合是一项开创性的发展&#xff0c;尤其是在建筑、工程和施工&#xff08;AEC&#xff09;行业。本文探讨了数字孪生与VR技术的协同整合&#xff0c;阐明了它们如何彻底改变用户体验和运营效…