Java基础(6)-ArrayList和LinkedList一览

Java中对比Vector, ArrayList, LinkedList的区别 创作不易,请大家多多支持。我们在日常的工作中,能够高效地管理和操作数据是非常重要的。由于每个编程语言支持的数据结构不尽相同,比如我最早学习的 C语言,需要自己实现很多基础数据结构,管理和操作会比较麻烦。相比之下,Java 则要方便的多,针对通用场景的需求,Java提供了强大的集合框架,大大提高了开发者的生产力。今天我要问你的是有关集合框架方面的问题,对比Vector、ArrayList、LinkedList 有何区别? 阅读详情

今天无聊,学学ArrayList和LinkedList

1.1 ArrayList底层实现

1.容量不固定,有最大阈值,但一般达不到
2.有序的(元素输出顺序与输入顺序一致)
3.元素可以为 null
4.效率高
5.由于基于数组实现,所以size(), isEmpty(), get(), set(), iterator(), ListIterator() 方法的时间复杂度都是 O(1) add() 添加操作的时间复杂度平均为 O(n) 其他所有操作的时间复杂度几乎都是 O(n)
6.占用空间更小,对比 LinkedList,不用占用额外空间维护链表结构,ArrayList的底层实现是基于数组的,所以它的get(int i)方法和set(int i, E e)方法都是通过索引直接定位到数组中, 所以这两个方法的时间复杂度都为O(1)常数级别,而remove(E e)方法的时间复杂度为O(n)级别,因为在remove的过程中需要遍历数组确定该元素的位置并进行删除,其他方法的时间复杂度也约为O(n) 级别
7.是Fail-fast机制的
8.是非同步的

E elementData(int index) {
    return (E) elementData[index];
}

//获取
public E get(int index) {
	//范围检查
    rangeCheck(index);
    //直接根据数组角标返回元素,时间复杂度为O(1)
    return elementData(index);
}

//修改
public E set(int index, E element) {
    rangeCheck(index);
    E oldValue = elementData(index);

    //直接对数组操作
    elementData[index] = element;
    //返回原来的值
    return oldValue;
}


public boolean add(E e) {
    //对数组的容量进行调整
    ensureCapacityInternal(size + 1);  
    elementData[size++] = e;
    return true;
}

//根据位置删除
public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

   
    int numMoved = size - index - 1;
    if (numMoved > 0)
    	
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    //原数组中最后一个元素删掉
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

public void add(int index, E element) {
		//范围检查
        rangeCheckForAdd(index);
		//调整大小
        ensureCapacityInternal(size + 1); 
        //将从index开始的元素向后复制移一位:
        //1,2,3  add(1, 4) -> 1,2,2,3 
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        //将index设置为element
        //1,2,3  add(1, 4) -> 1,2,2,3 -> 1,4,2,3
        elementData[index] = element;
        size++;
}
    
//删除某个元素
public boolean remove(Object o) {
    if (o == null) {
        //挨个遍历找到目标
        for (int index = 0; index < size; index++)
            if (elementData[index] == null) {
                //快速删除
                fastRemove(index);
                return true;
            }
    } else {
        for (int index = 0; index < size; index++)
            if (o.equals(elementData[index])) {
                fastRemove(index);
                return true;
            }
    }
    return false;
}

//内部方法,“快速删除”,忽略边界条件
private void fastRemove(int index) {
    modCount++;
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null;  
}

1.2 ArrayList基本参数

  • 底层数据结构,数组transient Object[] elementData

  • 数组初始化容量为10 private static final int DEFAULT_CAPACITY = 10;

  • 当前元素的个数 private int size;

  • 数组最大容量2^31 - 8 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

1.3 grow(int capacity) 扩容方法(1.5倍扩容)

private void grow(int minCapacity) {
        //旧数组的长度
        int oldCapacity = elementData.length;
        //新数组的长度为旧数组长度的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //如果新的扩容长读要大于ArrayList规定的最大长度,那么新长度则为int型最大长度
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //可以扩容,直接调用Arrays,copyOf方法(这个一个native方法),新开辟一块指定长度的
        内存存储新数组元素
        elementData = Arrays.copyOf(elementData, newCapacity);
    }  

例如在ArrayList中插入25个元素时,将会扩容3次:
size 11 —> 16 —> 23 —>25
capacity 10—>15—>22—>33

1.4 ArrayList具有RandomAccess的性质

所以使用for循环遍历获取元素会比使用迭代器获取元素的速度会更快一些(因为是基于设置的,若是基于链表的,那么使用迭代器遍历会快一些)

1.5 LinkedList基本概述

1.基于双端链表实现,底层节点为双向链表
2.删除元素和添加元素的时间复杂度为O(1),查找元素的时间复杂度为O(n)
3.允许元素为null
4.是有序的
5.是Fail-fast机制的
6.是非同步的
7.不需要扩容

	//双向链表节点
	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;
        }
    }
	//整体是基于一个双端链表的
	transient Node<E> first;
    transient Node<E> last;

1.2 其他实现

其实就是链表的常规代码而已,需要注意迭代器中的modCount标识

程序设计二(面向对象)_实训13_虚函数 已有List类,以及其2个派生类ArrayList和LinkedList。为其编写一个IList类。IList类在逻辑上为这个继承体系提供一个接口。建立一个继承体系,List是基类,ArrayList和LinkedList是其派生类。做一个流输出运算符重载,其第二个参数是List的常引用类型。List是基类,ArrayList和LinkedList是派生类。List提供5个函数,分别是增删查改显。其中,前4个是纯虚函数,第5个是虚函数。用户需在ArrayList和LinkedList中编写实现相应的实现。 阅读详情

相关推荐

C++面向对象 - 多态性的应用

List 类提供 5 个虚函数,其中有 4 个是纯虚函数,需要用户在子类中实现。这上面的调用显然都是合法的。但是现在要求实现如下效果:第 3 行的函数执行的是适合 ArrayList 输出的代码,而第 4 行执行的是适合 LinkedList 输出的代码。即,虽然调用的函数一样,但需要根据当时的实参类型选择合适的实现。用户需要编写 IList 类,IList 类只提供 5 个纯虚函数,分别是增、删、查、改和显示函数。但是对面向对象的基础而言(对 C++ 而言就是公有继承),重要的是公有函数的继承。

Junds0的博客 2555

程序设计二(面向对象)_实训13_虚函数实验答案补充2

建立一个继承体系,List是基类,ArrayList和LinkedList是其派生类。并且编写实现下述函数并达到如下效果。做一个流输出运算符重载,其第二个参数是List的常引用类型。我们知道子类的对象天生可以作为父类类型使用,因此这上面的调用显然都是合法的。但是现在要求实现如下效果:第 3 行的函数执行的是适合ArrayList输出的代码,而第 4 行执行的是适合LinkedList输出的代码。即,虽然调用的函数一样,但需要根据当时的实参类型选择合适的实现。相当于对非成员函数做到动态绑定。

qq_65628600的博客 3096

电子取证之服务器取证思路

服务器取证是一个技术性很强的领域,涉及到多个环节,包括网站重构、网站代码分析、容器分析等。数据库密码的获取通常通过查看配置文件、日志文件、备份等途径,同时可以通过一些绕过技术如禁用身份验证来获取权限。对于不同的数据库,需要根据其特性采取相应的应对方法和命令。

2401_84830066的博客 2492

List继承体系

List接口

吹 梦到西州的博客 415

从零构建SOEM主站:基于STM32的EtherCAT伺服控制实战指南

本文详细介绍了如何从零构建基于STM32的SOEM主站系统,实现EtherCAT伺服电机的高精度控制。通过硬件选型、SOEM协议栈移植、PDO/SDO配置优化等实战步骤,帮助开发者掌握工业自动化中的关键运动控制技术,特别适用于23位编码器伺服电机的应用场景。

weixin_29186249的博客 667

Simulink Test Sequence实战:5步搞定复杂逻辑测试(附Excel模板)

本文详细介绍了如何利用Simulink Test Sequence模块高效完成复杂逻辑测试。通过对比传统Excel方法的不足,阐述了Test Sequence以流程图和自然语言描述测试场景的优势,并提供了从环境搭建、逻辑构建到与Test Manager集成、利用Excel模板进行数据驱动的完整5步实战指南,帮助工程师将复杂的状态机或逻辑流测试从繁琐的‘体力活’转变为高效的‘技术活’。

snow3的博客 251

数据分析的NumPy模块(一):初始NumPy模块、数组的基本操作(内置数组创建方法、随机数组抽样、文件 I/O 创建数组、ndarray数组属性)

文章目录一.初识NumPy模块1.简介2.数据类型3.从图片认识numpy4.数组对象ndarray二.NumPy中数组的基本操作1.内置的数组创建方法(1)从列表或元组转换(2)arange 方法创建(3)linspace 方法创建(4)ones 方法创建(5)zeros 方法创建(6)full方法创建(7)eye 方法创建 一.初识NumPy模块 1.简介 (1)概念 NumPy(Numerical Python) 是 Python 语言的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算

YFater的博客 621

NS3入门教程 以及 NS3 IEEE 802.15.7 CSMA/CA仿真代码

本文初衷 当我发现我必须要做NS3网络仿真的时候,我内心是拒绝的,一方面NS3完全没接触过,另一方面,C++语言接触也不是太多,感觉工作量好大。但是,真的是不做不行了。然后,我就到网上查一些关于NS3的仿真内容,入门什么的,感觉真的是好混乱啊,这个东西没有一个明确的教程,都是一些杂乱的优快云和技术博客,看起来十分混乱,而且有些现成的代码都是好多好多年前的,让人很难受。所以,我就写了本文,希望...

逆水行舟,不进则退 6739

Java集合ArrayList和LinkedList区别

Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口。 Java集合大致可以分为Set、List、Queue和Map四种体系,其中Set代表无序、不可重复的集合;List代表有序、重复的集合;而Map则代表具有映射关系的集合;Queue体系集合,代表一种队列集合实现。 jdk1.4以前没有Queue集合,一般用Linked...

怀素的专栏 1万+

Matt Pocock Skills — AI 编码代理技能包介绍与使用指南

《Matt Pocock Skills:AI编码代理技能包指南》 摘要: Matt Pocock Skills是一套开源AI编码代理技能包,旨在解决AI辅助开发中的四大痛点:需求理解偏差、token浪费、代码质量差和架构腐化。该技能包包含多种实用工具:/grill-with-docs用于需求对齐,/tdd实现测试驱动开发,/diagnose提供规范化调试流程,/triage管理issue生命周期。核心思想包括:通过拷问式对齐确保需求理解一致,建立共享领域语言提高沟通效率,快速反馈闭环加速开发,以及持续架构维

qq_45859163的博客 2225

手把手教你用Wireshark抓包分析BLE广播包:从PDU结构到AD Type实战解析

本文详细介绍了如何使用Wireshark工具抓取并分析BLE广播包,从PDU结构到AD Type的实战解析。通过硬件设备选择、软件配置、协议栈解析及高级故障排查,帮助开发者深入理解蓝牙低功耗通信机制,提升物联网设备调试效率。

weixin_30482383的博客 418

Java面试:ArrayList 和 LinkedList 的区别是什么?谈谈你对ArrayList和LinkedList的理解

ArrayList是基于动态数组实现的 List,其中元素的索引是基于顺序的。它提供了按索引访问元素的快速方式,适合需要频繁读取元素的场景。ArrayList 和 LinkedList 各有优缺点,选择合适的集合类将直接影响程序的性能和可维护性。了解它们的特性及适用场景可以帮助开发者更有效地管理数据结构,从而优化应用程序的性能。希望本篇博客能够帮助你更好地理解 ArrayList 和 LinkedList,并在未来的项目中作出明智的选择!

智通全网络工作室的博客 2603

万象RK3506-EG1800网关使用说明

摘要:HD-RK3506-EG1800是一款高性能工业物联网边缘计算网关,支持Buildroot和Ubuntu双系统。文档详细介绍了网关的网络配置(包括ETH0/ETH1的静态IP设置、WiFi连接)、时钟同步、HSL软件安装配置(含开机自启动服务)、系统日志优化以及刷机操作指南(Loader/Maskrom模式)。特别提供了基于lighttpd的网页管理方案,通过HTML界面实现网络参数可视化配置,包含身份验证、实时状态显示和表单提交功能。网关默认ETH0固定IP为192.168.1.10,提供完整的CL

tian_jiangnan的博客 179

ArrayList 和 LinkedList 的区别

ArrayList 和 LinkedList 的区别 ArrayList基于动态数组实现的非线程安全的集合;LinkedList基于链表实现的非线程安全的集合。 对于随机index访问的get和set方法,一般ArrayList的速度要优于LinkedList。因为ArrayList直接通过数组下标直接找到元素;LinkedList要移动指针遍历每个元素直到找到为止。 新增和删除元素,一...

ConstXiong 4万+

AI爬虫:一文讲通AI爬虫技术和原理,及34个AI爬虫工具推荐

AI 爬虫 是一种结合了传统网络爬虫技术和人工智能(AI)技术的工具,能够更智能、高效地从网页中提取和处理数据。与传统爬虫相比,AI 爬虫能够更好地处理动态内容、复杂网页结构以及非结构化数据,同时具备数据清洗、分类、情感分析等高级功能。

数据知道的博客 1万+

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

【Java】ArrayList与LinkedList详解!!!

在集合框架中,List就是一个接口继承于Collection接口。在数据结构的角度,List就是一个线性表,即n个具有相同类型元素的有限序列,在该序列上可以执行增删查改以及变量等操作。什么是线性表?线性表是由n个具有相同类型元素组成的有限序列。线性表是一种常见的数据结构。在逻辑上,线性表是一种线性结构,就是连续的一条直线,在物理结构上,不一定是连续的,在物理存储是,通常是以数组和链式的结构形式存储。常见的线性比表有顺序表、链表、栈、队列.......ArrayList是一个普通的类,是顺序表的一种,

2301_80543957的博客 5623

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

Java——LinkedList 和 ArrayList的全面对比讲解

你前后都有一个人,想插队的话,你只需要拉住你前面和后面的人,让他们也拉住你。:因为数据是通过链表存储的,要访问某个特定位置的元素,你需要从头(或尾)开始,逐个走过每个节点才能找到目标⚙️。因为你只需要拉住你前面和后面的人,告诉他们换一下顺序,所以插入和删除非常方便,效率高🏆。:由于每个节点除了存储数据外,还要存储指向前后节点的两个指针🧷,所以相比ArrayList,它占用的内存更多📊。:ArrayList就像是一个紧凑的货架,所有商品整齐排列,没有多余的“拉绳子”的动作,所以它更加节省空间💡。

weixin_44748929的博客 3837

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

java中的ArrayList和LinkedList的底层剖析

LinkedList也是一个动态的线性表,所以它就必须能够存储元素,能够获取大小,ArrayList底层是通过一个数组存储元素,LinkedList内部是通过一个结点类来存储元素,同时这个Node里面有两个指针,prev指向前一个结点、next指向下一个结点,同时提供一个构造方法,当我们需要添加一个元素的时候本质是添加一个结点,再把这个元素放入到这个结点内部,同时维护好这个结点的前后结点。我们要对数组进行封装,也就是让这个数组如果元素装满了之后,重新创建一个更大的数组,将原来的元素复制过去。

qq_64039411的博客 2692

ArrayList 和LinkedList的区别比较

‌ArrayList和LinkedList的主要区别在于它们的底层数据结构、性能特点以及适用场景。‌ArrayList和LinkedList从名字分析,他们一个是Array(动态数组)的数据结构,一个时Linked(链表)的数据结构,此外,他们两个都是对List接口的实现。前者是数组队列,相当于动态数组;后者为双向链表结构,也可当作堆栈、队列、双端队列。

A_aspectJ的博客 4569

JAVA中LinkedList和ArrayList的区别

1.底层数据结构ArrayList:基于动态数组,内存连续储存LinkedList:基于双向链表,节点包含前后指针​2.访问性能​ArrayList:随机访问O(1)(直接索引)LinkedList:随机访问O(n)(需遍历)3.​插入/删除性能​ArrayList:中间/头部操作O(n)(需移动元素)尾部操作O(1)(扩容时O(n))中间操作O(n)(遍历)+O(1)(修改指针)头尾操作O(1)4.​适用场景​优先ArrayList:高频随机访问/尾部操作/内存敏感场景。

imxiaoxin09的博客 1258

ArrayList和LinkedList的区别:如何选择?

方法,先将 succ 的前一个节点(prev)存放到临时变量 pred 中,然后生成新的 Node 节点(newNode),并将 succ 的前一个节点变更为 newNode,如果 pred 为 null,说明插入的是队头,所以 first 为新节点;大家都知道,数组是定长的,就是说,数组一旦声明了,长度(容量)就是固定的,不能像某些东西一样伸缩自如。比如说,默认的数组大小是 10,当添加第 11 个元素的时候,数组的长度扩容了 1.5 倍,也就是 15,意味着还有 4 个内存空间是闲置的,对吧?

sunyan5211314的博客 1562

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

数组(Array)ArrayList和LinkedList都是用于存储数据的容器,但它们在存储机制、性能、使用场景等方面有着显著的区别。了解这些区别能帮助我们在不同场景下选择最适合的数据结构。数组是最基本的数据结构之一,用于存储固定大小的同类型元素的集合。每个元素都可以通过其索引进行访问。特点:固定大小:数组一旦创建,大小不能改变。索引访问:数组的每个元素通过索引访问,时间复杂度为O(1)。内存连续:数组在内存中是连续分配的,这使得数组访问速度非常快,但增加和删除操作会比较复杂。

lenyan~的博客 1306

Java 中 ArrayList 和 LinkedList 的区别及使用场景

在 Java 中,`ArrayList` 和 `LinkedList` 是两种常用的集合类,它们都实现了 `List` 接口,但在底层实现、性能特点以及适用场景上有显著区别。本文将详细分析它们的区别,并探讨如何在实际开发中选择合适的集合类。

李长渊的博客 1443

请简述Java中ArrayList和LinkedList的区别以及它们的用途

在Spring框架中,和都是用于管理bean的组件,它们在功能上有所区别。:在Spring早期版本中,它是主要的bean工厂,负责创建和管理bean。它提供了一种基于XML的配置方式,通过这种方式,你可以定义bean的属性、依赖关系等。然而,由于XML配置文件的使用相对繁琐,且不易于维护,因此Spring 3.0开始引入了新的组件——。:它是Spring 3.0之后引入的一个高级组件,它是的升级版。支持基于Java的配置(如使用Java Config),这种配置方式更为简洁,易于理解。

WangYaolove1314的博客 2111

ArrayList和LinkedList详解

ArrayList是Java集合框架中的一个核心类,它实现了List接口,底层基于数组实现。作为一种动态数组,ArrayList克服了Java原生数组长度固定的局限性,能够根据需要动态调整容量。基于数组实现:ArrayList内部维护了一个Object类型的数组,用于存储元素。动态扩容:当元素数量超过当前数组容量时,ArrayList会自动扩容,通常是将容量增加到原来的1.5倍。随机访问高效:由于数组支持通过索引直接访问元素,ArrayList的随机访问性能非常好,时间复杂度为O(1)。顺序存储。

weixin_56018532的博客 1267

Java中ArrayList和LinkedList的比较

关于 ArrayList 和 LinkedList 在添加 (add) 和删除 (remove) 操作上的性能比较,传统观点认为由于 ArrayList 需要移动数据,而 LinkedList 只需调整链表指针,因此 LinkedList 更快。然而,实际性能并不是这么简单,两者在不同情况下的表现差异较大,在Java中,ArrayList和LinkedList都是常用的列表实现类,它们都实现了List接口,但在内部工作原理和性能方面有显著差异。

m0_74293254的博客 1323
上一篇: 算法学习笔记(9)-回溯算法与八皇后问题
下一篇: Java基础(7)-ConcurrentHashMap与CAS
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值