java开发面试:常见集合ArrayList的源码分析,数组和List的相互转换

ArrayList

底层数据结构——数组

寻址公式

a[i] = baseAddress + i *dataTypeSize
即,数组的首地址+索引乘以存储数据的类型大小。

为什么数组索引从0开始呢?从1开始不行吗?

实际上并不是不行。而是如果数组索引从1开始的话,整体性能会变低。
因为寻址公式会变为a[i] = baseAddress + (i-1) *dataTypeSize,也就是说,多了一个减法操作。

查找/插入/删除的时间复杂度

  1. 查找
    • 通过下标查询的时间复杂度是O(1)
    • 未知下标查询的时间复杂度是O(n)
    • 未知下标但排序,通过二分查找的时间复杂度是O(logn)
  2. 插入,O(n)
  3. 删除,O(n)

数组和List(集合)的转换

数组转List ,使用JDK中java.util.Arrays工具类的asList方法
List转数组,使用List的toArray方法,参数为指定长度的数组实例化对象。如果无参,toArray方法返回 Object数组。

示例代码:

//数组转List
public static void testArray2List(){String[] strs = {"aaa","bbb","ccc"};List<String> list = Arrays.asList(strs);for (String s : list) {System.out.println(s);}
}
//List转数组
public static void testList2Array(){List<String> list = new ArrayList<String>();list.add("aaa");list.add("bbb");list.add("ccc");String[] array = list.toArray(new String[list.size()]);for (String s : array) {System.out.println(s);}
}
数组转List后修改了数组内容,list受影响吗/List转数组后,修改了List内容,数组受影响吗

Arrays.asList转换list之后,如果修改了数组的内容,list会受影响,因为它的底层使用的Arrays类中的一个内部类ArrayList来构造的集合,在这个集合的构造器中,把我们传入的这个集合进行了包装而已,最终指向的都是同一个内存地址。

list用了toArray转数组后,如果修改了list内容,数组不会影响,当调用了toArray以后,在底层是它是进行了数组的拷贝,跟原来的元素就没啥关系了,所以即使list修改了以后,数组也不受影响

源码分析

成员变量

private static final int DEFAULT_CAPACITY = 10;// 初始容量,默认等于10
private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData;//ArrayList的数组(实际存储数据的数组)
private int size; //ArrayList的大小(实际包含的元素)

EMPTY_ELEMENTDATA :
无参构造 ArrayList 对象,且没有指定初始容量时,ArrayList 内部的 elementData 数组将会被初始化为 EMPTY_ELEMENTDATA。

通过这种方式,在初始时节省了内存空间,只有在首次添加元素时才会真正分配内部数组的容量。

代码如下:

import java.util.ArrayList;
public class EmptyElementDataExample {public static void main(String[] args) {// 使用无参构造方法创建 ArrayList 对象ArrayList<String> list = new ArrayList<>();// 添加元素list.add("Apple");list.add("Banana");}
}

DEFAULTCAPACITY_EMPTY_ELEMENTDATA:
通过带有指定初始容量的构造方法创建 ArrayList 对象,并将初始容量设置为 0时,ArrayList
内部的 elementData 数组会被初始化为 DEFAULTCAPACITY_EMPTY_ELEMENTDATA。

多加一个DEFAULTCAPACITY_EMPTY_ELEMENTDATA是为了区分使用了初始容量为 0 的构造方法和无参构造方法的情况,避免了两种情况下 elementData 指向同一个空数组的问题。

代码如下:

import java.util.ArrayList;
public class DefaultCapacityEmptyElementDataExample {public static void main(String[] args) {// 使用带有指定初始容量的构造方法,并设置初始容量为 0ArrayList<String> list = new ArrayList<>(0);// 添加元素list.add("Apple");list.add("Banana");}
}

elementData :
使用带有指定初始容量的构造方法时,elementData初始化为长度为指定初始容量的数组。

需要注意的是,elementData被transient关键字修饰,所以不会被默认的序列化机制持久化保存,即,不会转化为字节流,从而节省存储空间和序列化的时间开销。

代码如下:


import java.util.ArrayList;
public class ElementDataExample {public static void main(String[] args) {// 使用带有指定初始容量的构造方法,并设置初始容量为 5ArrayList<String> list = new ArrayList<>(5);// 添加元素list.add("Apple");list.add("Banana");// 获取内部的 elementData 数组Object[] elementData = list.toArray();System.out.println("elementData数组长度:" + elementData.length);}
}

add方法

  1. 确保数组已使用长度(size)加1之后足够存下下一个数据​
  2. 如果当前数组已使用长度+1后大于当前的数组长度(elementData.length),则调用grow方法扩容到当前数组长度的1.5倍。
  3. 确保新增的数据有地方存储之后,则将新元素添加到位于size的位置上。​
  4. 返回添加成功的布尔值。

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

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

相关文章

AUTOSAR从入门到精通-存储配置(NvM)(三)

目录 前言 几个高频面试题目 ​autosar架构中,nvm运行在核1,那么核0的程序如何使用nvm 原理

【华为机试】2023年真题B卷(python)-猜密码

一、题目 题目描述&#xff1a; 小杨申请了一个保密柜&#xff0c;但是他忘记了密码。只记得密码都是数字&#xff0c;而且所有数字都是不重复的。 请你根据他记住的数字范围和密码的最小数字数量&#xff0c;帮他算下有哪些可能的组合&#xff0c;规则如下&#xff1a; 1、输出…

使用阿里云性能测试工具 JMeter 场景压测 RocketMQ 最佳实践

作者&#xff1a;森元 需求背景 新业务上线前&#xff0c;我们通常需要对系统的不同中间件进行压测&#xff0c;找到当前配置下中间件承受流量的上限&#xff0c;从而确定上游链路的限流规则&#xff0c;保护系统不因突发流量而崩溃。阿里云 PTS 的 JMeter 压测可以支持用户上…

【C++初阶】第一站:C++入门基础(下)

前言&#xff1a; 紧接着上两篇文章&#xff0c;c入门基础(上)&#xff1a;C入门基础(上) c入门基础(中)&#xff1a;C入门基础(中) 继续补充完c初阶入门基础的知识点&#xff0c;本章知识点包括&#xff1a; 引用和指针的区别、内联函数、auto关键字(C11)、基于范围的for循环…

使用 Layui 的 template 模块来动态加载select选项

可以使用 Layui 的 template 模块来动态加载选项&#xff0c;如下所示&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>Layui 动态模板示例</title><link rel"stylesheet" href"pat…

Android 13 - Media框架(24)- OMXNodeInstance(一)

为了了解 ACodec 是如何与 OpenMAX 组件进行 buffer 流转的&#xff0c;我们有必要先来学习 OMXNodeInstance&#xff0c;在前面的章节中&#xff0c;我们已经了解了 media.codec 进程包含的内容&#xff0c;以及 OpenMAX 框架中的一些内容。这一节我们将来学习 OMXNode 与 med…

JUC、MySQL

java后端面试题大全 1.JUC1.1 ReentrantLock(可重入独占式锁)&#xff08;难度&#xff1a;★★★ 频率&#xff1a;★★&#xff09;1.2 ReentrantLock比synchronized的优点&#xff08;难度&#xff1a;★★★ 频率&#xff1a;★★&#xff09;1.3 CAS的原理和优缺点1.4 syn…

快猫视频模板源码定制开发 苹果CMS 可打包成双端APP

苹果CMS快猫视频网站模板源码&#xff0c;可用于开发双端APP&#xff0c;后台支持自定义参数&#xff0c;包括会员升级页面、视频、演员、专题、收藏和会员系统等完整模块。还可以直接指定某个分类下的视频为免费专区&#xff0c;具备完善的卡密支付体系&#xff0c;无需人工管…

Git 中 rebase、reset、revert 有什么区别?

在Git中&#xff0c;rebase、reset和revert是三个常用的操作命令&#xff0c;它们用于处理合并分支、回退版本、撤销更改。 区别&#xff1a; 1、rebase&#xff08;变基&#xff09;&#xff1a;git rebase命令用于将一个分支的提交应用到另一个分支上&#xff0c;从而重新组…

听GPT 讲Rust源代码--src/tools(17)

File: rust/src/tools/rust-analyzer/crates/profile/src/hprof.rs 在Rust源代码中&#xff0c;rust/src/tools/rust-analyzer/crates/profile/src/hprof.rs文件是rust-analyzer中的性能分析模块&#xff0c;用于代码运行时的性能统计和分析。下面将详细介绍每个结构体的作用&a…

【操作系统】什么是进程?

文章目录 进程进程的属性进程的状态挂起 进程 进程是一个可并发执行的具有独立功能的程序关于某个数据集合的执行过程&#xff0c;也是操作系统进行资源分配和保护的基本单位。 进程的属性 结构性&#xff1a; 共享性&#xff1a;同一程序运行于不同数据集合上构成不同的进程…

Flink Table API 与 SQL 编程整理

Flink API总共分为4层这里主要整理Table API的使用 Table API是流处理和批处理通用的关系型API&#xff0c;Table API可以基于流输入或者批输入来运行而不需要进行任何修改。Table API是SQL语言的超集并专门为Apache Flink设计的&#xff0c;Table API是Scala和Java语言集成式…

一文学会 Apache Zeppelin

Zeppelin资料 Zeppelin项目信息 Zeppelin官网 http://zeppelin.apache.org/Zeppelin源码地址 https://github.com/apache/zeppelinZeppelin JIRA: https://issues.apache.org/jira/projects/ZEPPELIN/summaryZeppelin文档 Flink on Zeppelin 文档集中地 https://www.yuque.co…

176.【2023年华为OD机试真题(C卷)】整数对最小和(贪心算法(Greedy Algorithm)实现JavaPythonC++JS)

🚀你的旅程将在这里启航!本专栏所有题目均包含优质解题思路,高质量解题代码,详细代码讲解,助你深入学习,深度掌握! 文章目录 【2023年华为OD机试真题(C卷)】整数对最小和(遍历和条件判断实现Java&Python&C++&&JS)题目描述解题思路题解代码Python题…

【漏洞复现】奥威亚 教学视频应用服务平台任意文件上传漏洞

漏洞描述 AVA 教学视频应用服务平台是由广州市奥威亚电子科技有限公司基于当前教育视频资源建设的背景及用户需求的调研,开发出来能够适应时代发展和满足学校需求,具有实效性、多功能、特点鲜明的平台。 该平台存在任意文件上传漏洞,通过此漏洞攻击者可上传webshell木马,…

Promise.all()和Promise.race()

参考文章 Promise.all() Promise.all()方法用于将多个 Promise 实例&#xff0c;包装成一个新的 Promise 实例。 const p Promise.all([p1, p2, p3]);上面代码中&#xff0c;Promise.all()方法接受一个数组作为参数&#xff0c;p1、p2、p3都是 Promise 实例&#xff0c;如果…

【DP】62.不同路径

题目 法1&#xff1a;二维DP 必须掌握&#xff01; class Solution {public int uniquePaths(int m, int n) {int[][] matrix new int[m][n];Arrays.fill(matrix[0], 1);for (int i 0; i < m; i) {matrix[i][0] 1;}for (int i 1; i < m; i) {for (int j 1; j <…

OpenCV-9颜色空间的转换

颜色转换API&#xff1a;cvtColor&#xff08;img&#xff0c;colorsapce&#xff09; cvt含义为转换 convesion(转换) 下面为示例代码&#xff1a; import cv2# callback中至少有一个参数 def callback(value):passcv2.namedWindow("color", cv2.WINDOW_NORMAL) …

C#上位机与欧姆龙PLC的通信03----创建项目工程

1、创建仿真PLC 这是一款CP1H-X40DR-A的PLC&#xff0c;呆会后面创建工程的时候需要与这个类型的PLC类型一致&#xff0c;否则程序下载不到PLC上。 2、创建虚拟串口 首先安装&#xff0c;这个用来创建虚拟串口来模拟真实的串口&#xff0c;也就是上位机上有那种COM口&#xf…

Java版直播商城免 费 搭 建:电商、小程序、三级分销及免 费 搭 建,平台规划与营销策略全掌握

随着互联网的快速发展&#xff0c;越来越多的企业开始注重数字化转型&#xff0c;以提升自身的竞争力和运营效率。在这个背景下&#xff0c;鸿鹄云商SAAS云产品应运而生&#xff0c;为企业提供了一种简单、高效、安全的数字化解决方案。 鸿鹄云商SAAS云产品是一种基于云计算的软…