ArrayList和LinkedList

ArrayList的注意事项

1、在ArrayList中可以放任意元素,包括空值,任何元素,且可重复添加。

2、ArrayList底层是由数组来实现数据存储的

3、ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),看源码

在多线程的情况下,不建议使用ArrayList。

ArrayList底层操作机制源码分析

1、ArrayList 中维护了 一个Object类型的数组 elementData.

transient Object[] elementData;

transient: 表示瞬间、短暂的,表示该属性不会被序列化
在这里插入图片描述

2、当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData的容量为0, 第一次添加,则扩容elementData为10,如果需要再次扩容的话,则扩容elementData为1.5倍

3、如果使用的是指定容量capacity的构造器,则初始的elementData容量为capacity,如果需要扩容,则扩容至当前elementData的1.5倍。

4、当添加元素时,先判断是否需要扩容,如果需要扩容,则调用grow方法。

重要、重要、重要!!!

上面的总结是基于之前的代码,现在新版本的源码已经改变,扩容机制也已经更改,可以看下面的👇🏻的源码分析。

源码解析

  • 无参构造器创建
ArrayList list = new ArrayList();

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

示例代码,可将代码复制至idea进行调试总结

package com.zhang.test_package.list_;import java.util.ArrayList;public class ArrayListSource {public static void main(String[] args) {// 使用无参构造器,默认容量为0ArrayList list = new ArrayList();// ArrayList list1 = new ArrayList(8);for (int i = 1; i <= 10; i++) {list.add(i);}list.addAll(1, list);for (int i = 11; i <= 15; i++) {list.add(i);}list.add(123);list.add(300);list.add(null);for (Object o :list) {System.out.println(o);}}
}

流程图:

小画桌-免费在线协作白板

Vector注意事项

1、Vector 中维护了一个Object类型的数组 elementData.

private Object[] elementData;

2、Vector是线程同步的,即支持线程安全,Vector类的操作方法中带有 synchronized

synchronized: 支持线程同步和互斥。

3、在开发中,如果需要线程同步安全时,优先使用Vector。

单线程的时候优先考虑使用ArrayList 方法(效率高)

Vertor扩容机制

在这里插入图片描述

1、无参构造器,默认的 initialCapacity 为10
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、之后扩容按照2倍扩容

在这里插入图片描述

LinkedList的底层结构

1、LinkedList 底层实现了 双向链表 和 双端队列 特点

2、可以添加任意元素(元素可以重复),包括null

3、线程不安全,没有实现同步。

LinkedList底层操作机制

1、LinkedList底层维护了一个双向链表

2、LinkedList中维护了两个属性,first和last,分别指向 首节点和尾节点

3、每个节点(Node对象),里面又维护了 prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终实现双向链表。

4、LinkedList 中的元素添加和删除,不是通过数组完成的,相对来说效率较高一些

package com.zhang.test_package.list_;public class LinkedList01 {public static void main(String[] args) {Node c = new Node("C++");Node java = new Node("java");Node python = new Node("Python");// 连接三个节点,形成双向链表//  c -> java -> pythonc.next = java; // 头节点java.next = python; // 尾结点// python -> java -> cpython.pre = java;java.pre = c;Node first = c; // 让first引用指向jack,就是双向链表的头结点Node last = python; //让last引用指向hsp,就是双向链表的尾结点System.out.println("正向遍历");while (first != null) {System.out.println(first);first = first.next;}System.out.println("反向遍历");while (last != null) {System.out.println(last);last = last.pre;}System.out.println("添加元素");}
}class Node{private Object item; // 保存节点处的数据public Node next;  // 下一个节点public Node pre;  // 上一个节点public Node(Object item) {this.item = item;}@Overridepublic String toString() {// 此处的toString方法不能加next和pre,不然的话,next和pre也都是Node,会调用toString方法// 最终StackOverFlowExceptionreturn "Node{" +"item=" + item +
//                ", next=" + next +
//                ", pre=" + pre +'}';}
}

数据结构的知识做基础。建议多学习数据基础相关的知识。

LinkedList分析流程图:

小画桌-免费在线协作白板

LinkedList的增删改查

package com.zhang.test_package.list_;import java.util.Iterator;
import java.util.LinkedList;public class LinkedListCRUD {public static void main(String[] args) {LinkedList linkedList = new LinkedList();for (int i = 0; i < 1000; i++) {linkedList.add(i);}
//        linkedList.add(1);
//        linkedList.add(2);
//        linkedList.add(3);
//        linkedList.add(4);
//        linkedList.add(5);System.out.println(linkedList);linkedList.remove(30);linkedList.set(2, 10);linkedList.get(2);Iterator iterator = linkedList.iterator();while (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next);}}
}

ArrayList和LinkedList比较

在这里插入图片描述
1、如果改查的操作多,选择ArrayList

2、如果增删的操作多,选择LinkedList

3、一般来说,在程序中,80%-90%的都是查询,因此大部分情况下选择ArrayList

4、在一个项目中,根据业务灵活选择,可以一个模块使用的是ArrayList,另一个模块是LinkedList.

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

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

相关文章

依赖注入三种方式,以及传统xml文件传参,还包括@Bean方式传参,还有Resource注入(详细版,每步都有提及)

获取bean对象&#xff0c;也称为对象装配&#xff0c;对象注入&#xff0c;依赖注入。 对象装配的实现方法有3种&#xff1a; 1.属性注入&#xff1b; 2.构造方法注入&#xff1b; 3.Setter注入。 再讲本节内容之前&#xff0c;我们先来提两个传参的方式&#xff0c;首先呢…

新手如何自学PostgreSQL(PG)

如果你是一个新手&#xff0c;想要自学PostgreSQL&#xff0c;下面是一些步骤和资源&#xff0c;可以帮助你入门&#xff1a; ①了解数据库基础知识&#xff1a;在开始学习PostgreSQL之前&#xff0c;建议你先了解一些数据库的基础概念和术语&#xff0c;例如表、列、行、SQL查…

什么是芯片组,南桥与北桥芯片的作用与区别

主板是连接计算机所有部件的PCB。在老式计算机中&#xff0c;所有芯片都分布在主板上。在现代计算机中&#xff0c;芯片数量减少并集中在特定位置。因此&#xff0c;将多个芯片组合起来形成一个芯片。这种可以替代大量芯片的芯片称为芯片组。主板上有一个芯片组。芯片组处理CPU…

echarts开发遇到的问题

echarts开发遇到的问题 1.rich富文本标签作为横向柱状图的刻度标签&#xff0c;其中带有icon。rich里不能写参数&#xff0c;只能写死&#xff1f;圆角设置无效&#xff1f; 解决办法&#xff1a; 自己写横向柱状图 散点图性能优化配置的临界点&#xff0c;最低优化数值必须…

day52

思维导图 比较指令结果的条件码 练习 汇编实现1-100的累加 .text .global _strat _start: mov r0,#0mov r1,#0 add_fun:add r0,r0,#1cmp r0,#100addls r1,r1,r0bls add_fun .end

微信小程序基于Promise封装发起网络请求

1.创建一个request.js // 相当于域名 const baseURL ***************; // 暴露一个request函数 export function request(parms) {// 路径拼接const url baseURL parms.url;// 请求体&#xff0c;默认为{}const data parms.data || {};// 请求方式&#xff0c;默认为GETco…

线性DP———最长公共子序列问题(LCS)

LCS问题 求两序列具有相同元素的最长子序列&#xff0c;我们可以用到动态规划的方法来解决问题 我们用 来表示序列 与序列 能组成的LCS的长度&#xff0c;的状态转移方程如下&#xff1a; 使用两层for循环就可以解决此问题&#xff0c;时间复杂度为,可以处理n<7000左右…

Windows 如何锁定文件

一、背景 如果应用程序有操作本地文件的功能&#xff08;如&#xff1a;读、写、复制、移动、删除等等&#xff09;&#xff0c;那么在测试或调试该应用程序时&#xff0c;肯定需要测试文件被其他应用程序锁定时&#xff0c;你的应用程序是如何处理的。 那么如何在本地模拟文件…

阿里云安装宝塔面板

阿里云安装宝塔面板 1.安装步骤2.需要加入安全组&#xff0c;打开端口3.安装宝塔 1.安装步骤 1.这里主要以阿里云的服务器 ECS为例子,需要安装纯净的系统 创建过程: 这边先用的是免费的: 2.需要加入安全组&#xff0c;打开端口 进入实例选项卡&#xff1a; 快速添加&…

二分类结局变量Logistic回归临床模型预测——分训练集和测试集(完结)

1. 介绍 2. 基线特征 3. 单因素多因素logistic回归分析及三线表 4. 构建临床列线图模型 5. 模型评价 6. 外部数据集验证 7. 另一种发文章的办法,分训练集和测试集,分析上述3-6节的内容 这里就讲一下如何分训练集和测试集,其余的步骤和之前是一样的,分训练集和测试集用…

126、仿真-基于51单片机16×16点阵滚动显示仿真设计(Proteus仿真+程序+配套资料等)

方案选择 单片机的选择 方案一&#xff1a;STM32系列单片机控制&#xff0c;该型号单片机为LQFP44封装&#xff0c;内部资源足够用于本次设计。STM32F103系列芯片最高工作频率可达72MHZ&#xff0c;在存储器的01等等待周期仿真时可达到1.25Mip/MHZ(Dhrystone2.1)。内部128k字节…

上市公司前端开发规范参考

上市公司前端开发规范参考 命名规则通用约定文件与目录命名HTML命名CSS命名JS命名 代码格式通用约定HTML格式CSS格式JS格式注释 组件组件大小单文件组件容器组件组件使用说明Prop指令缩写组件通讯组件的挂载和销毁按需加载第三方组件库的规定 脚手架使用规范移动端脚手架PC端脚…