Java ArrayList和LinkedList

ArrayList

ArrayList是Java中最常用的数据结构之一,它是一个动态数组的实现,允许你在程序中存储和管理一个可变大小的对象列表,我们可以添加或删除元素。

ArrayList 继承了 AbstractList ,并实现了 List 接口。

基本概念

ArrayList是List接口的一个实现类,它允许存储任意类型的对象,并且可以动态调整其大小。
List接口表示一个有序的集合,其中的元素可以重复,每个元素都有一个整数索引表示其位置。
动态数组:ArrayList使用一个数组作为其底层数据结构,当数组的空间不足时,ArrayList会自动扩展数组的大小。

内部结构

数组:ArrayList内部维护了一个对象数组,用于存储元素。
容量:ArrayList有一个内部的容量,即数组的大小。当添加的元素超过了当前容量时,ArrayList会创建一个新的更大的数组,并将旧数组中的所有元素复制到新数组中。
扩展策略:默认情况下,ArrayList在需要更多空间时会将数组的大小增加50%,但你可以通过构造函数指定初始容量或增量策略。

特点

可变性:ArrayList的大小是可变的,你可以随时添加或删除元素。
索引访问:ArrayList支持通过索引访问元素,这使得随机访问非常快。
线程不安全:ArrayList不是线程安全的,如果你需要在多线程环境中使用它,你需要自己进行同步控制。
允许null值:ArrayList允许存储null值。

常用方法

添加元素:add(E e) - 向列表的末尾添加一个元素。
获取元素:get(int index) - 返回指定索引处的元素。
设置元素:set(int index, E element) - 替换指定索引处的元素。
删除元素:remove(int index) - 删除指定索引处的元素。
迭代器:iterator() - 返回一个迭代器,用于遍历列表中的元素。

示例代码

下面是一个简单的示例,展示了如何使用ArrayList:

import java.util.ArrayList;
import java.util.List;public class ArrayListExample {public static void main(String[] args) {// 创建一个 ArrayListList<String> programmingLanguages = new ArrayList<>();// 添加元素programmingLanguages.add("Java");programmingLanguages.add("C");programmingLanguages.add("Python");programmingLanguages.add("C++");programmingLanguages.add("Visual Basic .NET");programmingLanguages.add("JavaScript");// 获取元素String firstLanguage = programmingLanguages.get(0);System.out.println("First language: " + firstLanguage);// 设置元素programmingLanguages.set(0, "Kotlin");System.out.println("Updated first language: " + programmingLanguages.get(0));// 删除元素programmingLanguages.remove(1); // 删除索引为1的元素System.out.println("After removing an element: " + programmingLanguages);// 遍历元素for (String language : programmingLanguages) {System.out.println(language);}}
}

当你运行这段代码时,它将输出更新后的列表和每个编程语言的名称。

深入理解

容量和扩展:ArrayList的默认初始容量为10。当添加元素导致当前数组容量不足时,ArrayList会创建一个新的数组,其大小通常是原数组大小的1.5倍,并将所有元素复制到新的数组中。
性能:由于ArrayList使用数组作为底层数据结构,因此随机访问非常快(O(1))。但是,插入或删除元素(尤其是在列表的中间位置)可能导致大量的元素移动,这可能会很慢(O(n))。
内存消耗:由于ArrayList可能需要预留额外的空间来容纳更多的元素,因此它可能会占用比实际需要更多的内存。

使用场景

当你需要一个可以动态扩展的有序列表时,ArrayList是一个很好的选择。
如果你需要频繁地进行随机访问,但插入和删除操作相对较少,那么ArrayList非常适合。
在需要快速随机访问的场景中,如索引数据库记录、缓存、配置文件等。

LinkedList

LinkedList是Java集合框架中的一个重要组成部分,它是一种基于双向链表实现的List接口。

基本概念

LinkedList是List接口的一个实现类,它使用双向链表来存储元素。
List接口定义了一个有序集合,允许重复元素,并且可以通过索引访问元素。
双向链表是一种数据结构,其中每个元素(节点)包含一个指向其前一个节点的引用和一个指向其后一个节点的引用。

内部结构

节点:LinkedList中的每个元素都是一个节点,每个节点包含两个部分:数据和两个引用(一个指向前一个节点,另一个指向后一个节点)。
头节点和尾节点:LinkedList维护了对头节点和尾节点的引用,这使得在链表两端添加和删除元素变得非常高效。

特点

插入和删除操作高效:由于LinkedList使用双向链表实现,因此在链表的任意位置插入或删除元素都非常高效,只需要更新相邻节点的引用即可。
随机访问较慢:与基于数组的ArrayList相比,LinkedList的随机访问(通过索引访问元素)较慢,因为需要从头节点开始遍历链表直到找到目标节点。
允许重复元素:LinkedList允许存储重复元素。
线程不安全:LinkedList不是线程安全的。如果多个线程同时访问或修改链表,则需要外部同步机制。

示例代码

下面是一个简单的示例,展示了如何使用LinkedList:

import java.util.LinkedList;
import java.util.List;public class LinkedListExample {public static void main(String[] args) {// 创建一个 LinkedListList<String> languages = new LinkedList<>();// 添加元素languages.add("Java");languages.add("C");languages.add("Python");// 在指定位置插入元素languages.add(1, "C++");// 删除元素languages.remove("C");// 获取元素String firstLanguage = languages.getFirst(); // 或者 languages.get(0)String lastLanguage = languages.getLast();// 遍历并打印元素for (String language : languages) {System.out.println(language);}}
}

当你运行这段代码时,它将输出:

Java
C++
Python

深入理解

内部实现:LinkedList的每个节点包含一个next引用指向下一个节点,一个prev引用指向前一个节点,以及一个item来存储实际的数据。
迭代器:LinkedList提供了高效的迭代器实现,可以用来遍历链表中的元素。
性能:LinkedList在插入和删除操作上的性能优于ArrayList,尤其是在链表的中间位置,但随机访问操作不如ArrayList高效。

使用场景

频繁的插入和删除操作:如果你需要在列表中频繁插入和删除元素,那么LinkedList是一个很好的选择。
不确定大小的列表:如果你不确定列表最终会有多大,或者列表的大小会动态变化,LinkedList是一个好的选择,因为它不需要像ArrayList那样预留额外的空间。
不需要频繁随机访问:如果大部分操作是插入和删除,并且不需要频繁地根据索引访问元素,那么LinkedList非常适合。

ArrayList、LinkedList和Vector的相同点和不同点

ArrayList, LinkedList, 和 Vector 都是 Java 中 List 接口的具体实现类,它们都提供了存储和操作有序集合的功能。下面是它们之间的一些相同点和不同点:

相同点

  1. 实现了 List 接口:

    • 它们都实现了 List 接口,因此支持 List 接口中定义的所有方法,比如 add(), remove(), get(), set() 等。

  2. 允许 null 元素:

    • 这三个类都允许在列表中存储 null 元素

  3. 索引访问:

    • 它们都可以通过索引来访问元素。

  4. 有序性:

    • 这些类都是有序的,即元素按照添加顺序保存。

  5. 可变性:

    • 它们都是可变的,意味着可以在列表中添加、删除或修改元素。

不同点

  1. 数据结构:

    • ArrayList: 基于动态数组实现。当空间不足时,会自动扩展数组的容量。

    • LinkedList: 基于双向链表实现。每个元素都有一个指向前一个元素和后一个元素的引用。

    • Vector: 与 ArrayList 类似,也是基于动态数组实现,但它是线程同步的。

  2. 性能特点:

    • ArrayList: 对于随机访问(如 get(int index) 和 set(int index, E element))非常高效,因为可以通过索引直接访问。但是插入和删除操作(尤其是中间位置的操作)效率较低,因为需要移动大量的元素。

    • LinkedList: 插入和删除操作非常快,因为它只需要改变前后节点的引用即可。然而,随机访问效率较低,因为需要从头开始遍历链表直到找到目标节点。

    • Vector: 性能特征类似于 ArrayList,但由于同步机制的存在,多线程环境下的性能较低。

  3. 线程安全性:

    • ArrayList 和 LinkedList: 都不是线程安全的。如果多个线程同时访问或修改这些列表,则需要外部同步机制。

    • Vector: 是线程安全的,它的许多方法都是同步的,可以直接在多线程环境中使用而不需要额外的同步。

  4. 初始化容量和增长策略:

    • ArrayList: 默认初始容量为10,每次扩容通常增加50%。

    • LinkedList: 没有固定的容量限制,因为它是基于链表实现的。

    • Vector: 默认初始容量为10,每次扩容通常增加100%。可以通过构造函数指定初始容量和增量。

  5. 其他特性:

    • Vector 还包含了一些额外的方法,例如 addElement(), insertElementAt(), removeElement(), removeElementAt(), 这些方法是为了向后兼容早期的 Vector API 设计。

选择哪个类取决于具体的应用场景。如果需要频繁地进行插入和删除操作,或者经常需要处理大量数据,LinkedList 可能更适合。如果需要快速随机访问,并且插入删除操作较少,那么 ArrayList 更合适。而 Vector 则适用于需要线程安全的场景。

 

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

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

相关文章

【Linux】ARM服务器命令行安装虚拟机

在Arm服务器上安装虚拟机操作笔记 一、基础环境准备1、环境准备2、检查KVM支持3、启动并启用libvirtd服务4、创建虚拟网络&#xff08;可选&#xff09;5、使用virt-manager创建虚拟机&#xff08;支持KVM&#xff09;6、管理虚拟机9、监控和日志 二、软虚拟化替代方案1、查看虚…

6. type *(0)的神奇之处

表达式 type * (0) 在 C/C 编程中是一个常见的技巧&#xff0c;通常用于内核编程和一些系统编程场景中。这种语法形式的主要作用是获取特定类型指针的虚拟地址 0&#xff0c;从而进行类型转换或执行其他计算。接下来我们会深入分析这个表达式的具体含义和应用。 1. 表达式的基…

GPT4o编写步进电机控制代码

我给出的要求如下&#xff1a; 基于STM32F407 HAL库&#xff0c;写一个步进电机控制程序&#xff0c;需要控制8个步进电机&#xff0c;我会给出描述步进电机的结构体变量&#xff0c;基于这些变量需要你做出以下功能&#xff0c;电机脉冲通过定时器中断翻转脉冲引脚的电平实现…

安科瑞电气防火在线保护器 ASCP210系列适用于汽车充电桩

安科瑞电气防火限流式保护器 传统保护方式采用电磁脱扣式断路器&#xff0c;检测到短路时&#xff0c;脱扣器动作&#xff0c;分断时间在毫米级&#xff0c;无法阻断短路电流。较好的方式是采用响应速度快的限流技术和器件。 电弧也有克星&#xff0c;可以微秒被扼杀在摇篮中&…

Vscode——如何实现 Ctrl+鼠标左键 跳转函数内部的方法

一、对于Python代码 安装python插件即可实现 二、对于C/C代码 安装C/C插件即可实现

【MySQL进阶之路】数据的查询

目录 建表 全列查询 指定列查询 查询表达式 指定别名 结果去重 WHERE 条件查询 模糊查询 结果排序 筛选分页结果 不同子句的执行顺序 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 建表 CREATE TABLE grades( id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT, name …

视觉巡线小车(STM32+OpenMV)——技术总结

在现代机器人技术中&#xff0c;视觉巡线是一种常见的导航方式&#xff0c;它允许机器人通过识别和跟踪地面上的线路来自主导航。本文将总结使用STM32微控制器和OpenMV视觉模块来实现视觉巡线小车的关键技术和步骤。 引言 视觉巡线小车是一种基于视觉识别技术的智能机器人&am…

CF 966 Div3 F. Color Rows and Columns

原题链接&#xff1a;Problem - F - Codeforces 题意&#xff1a;多测&#xff0c;每组测试数据给出n和k&#xff0c;n代表有n个长方形&#xff0c;k代表需要的到k分&#xff0c;每个长方形都有宽和高&#xff0c;每次可以填涂一个格子&#xff0c;如果填满一列或者一行就可以…

前端技巧——复杂表格在html当中的实现

应用场景 有时候我们的表格比较复杂&#xff0c;表头可能到处割裂&#xff0c;我们还需要写代码去完成这个样式&#xff0c;所以学会在原生html处理复杂的表格还是比较重要的。 下面我们来看这一张图&#xff1a; 我们可以看到有些表头项的规格不太一样&#xff0c;有1*1 2*…

雅菲奥朗 FinOps 认证培训:开启企业云财务管理转型之路

前言&#xff1a; 在当今快速变化的商业环境中&#xff0c;企业面临着前所未有的IT财务挑战。随着云计算和数字化转型的推进&#xff0c;传统的财务管理方式已经不能满足“企业上云”的需求。FinOps&#xff0c;即“云财务管理”应运而生&#xff0c;成为帮助企业实现IT财务流…

Oracle Index Partition索引分区的管理

Oracle索引分区的管理是数据库管理中的重要任务之一&#xff0c;它涉及索引的创建、维护、重建以及优化等多个方面。以下是对Oracle索引分区管理的详细解析&#xff1a; 一、索引分区的概念 索引分区&#xff08;Partitioned Index&#xff09;是针对分区表而言的&#xff0c…

虚幻引擎游戏开发 | 程序化生成道具位置 Randomize Height

当地图上有无数个收集物【如水晶】&#xff0c;一键随机化高度 应用前 应用后 这时候水晶的高度是离散型地在0和110两个数中平均概率地选择。 如果要有权重地分布高度&#xff0c;减少高位水晶的比例&#xff08;由于过多连续跳跃会让玩家无聊和难以持续专注&#xff09;可以加…

R语言统计分析——回归中的异常观测值

参考资料&#xff1a;R语言实战【第2版】 一个全面的回归分析要覆盖对异常值的分析&#xff0c;包括离群点、高杠杆点和强影响点。这些数据点需要更深入的研究&#xff0c;因为它们在一定程度上与其他观点不同&#xff0c;可能对结果产生较大的负面影响。 1、离群点 离群点是指…

[ACL 2024] Revisiting Knowledge Distillation for Autoregressive Language Models

Contents IntroductionMethodRethinking Knowledge Distillation for Autoregressive LMsImproving Knowledge Distillation with Adaptive Teaching Modes ExperimentsReferences Introduction 作者提出 Autoregressive KD with Adaptive Teaching Modes (ATKD)&#xff0c;通…

拦截器实现 Mybatis Plus 打印含参数的 SQL 语句

1.实现拦截器 package com.sample.common.interceptor;import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import or…

java之类和对象的介绍

1.面向对象和面向过程的概念&#xff1a; 面向对象&#xff1a;面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事。 面向过程&#xff1a;注重完成一件事情的过程&#xff0c;后续代码维护扩展较为麻烦。 以洗衣服为例&#xff0c;面向对象为传统…

模糊测试技术与高效模糊测试策略设计(第一篇)

一、概述 模糊测试&#xff08;Fuzzing&#xff09;是一种自动化测试技术&#xff0c;通过向目标软件输入大量随机或异常数据来发现潜在的安全漏洞。这种技术在软件安全研究中至关重要&#xff0c;尤其适用于发现未知漏洞。本文将详细讲解如何使用模糊测试工具&#xff0c;以及…

软件测试 |属性获取与断言

1.断言简介 断言时候UI自动化测试的三要素之一&#xff0c;是UI自动化测试中不可或缺的部分。我们使用定位器到定位元素后&#xff0c;通过测试脚本进行业务交互操作时&#xff0c;想要验证交互操作过程中的结果正确性就需要用到断言。 2.常规的UI自动化测试中使用的断言 在…

vue3基础ref,reactive,toRef ,toRefs 使用和理解

文章目录 一. ref基本用法在模板中使用ref 与 reactive 的区别使用场景 二. reactive基本用法在模板中使用reactive 与 ref 的区别使用场景性能优化 三. toRef基本用法示例在组件中的应用主要用途对比 ref 和 toRef 四. toRefs基本用法示例在组件中的应用主要用途对比 ref 和 t…

基于UE5和ROS2的激光雷达+深度RGBD相机小车的仿真指南(一)---UnrealCV获取深度+分割图像

前言 本系列教程旨在使用UE5配置一个具备激光雷达深度摄像机的仿真小车&#xff0c;并使用通过跨平台的方式进行ROS2和UE5仿真的通讯&#xff0c;达到小车自主导航的目的。本教程使用的环境&#xff1a; ubuntu 22.04 ros2 humblewindows11 UE5.4.3python8 本系列教程将涉及以…