[Java 面试题] ArrayList篇

1. ArrayList 与 数组的区别

ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。

2 ArrayList 的初始化容量
// 默认容量是10
private static final int DEFAULT_CAPACITY = 10;
// 如果容量为0的时候,就返回这个数组
private static final Object[] EMPTY_ELEMENTDATA = {};
// 使用默认容量10时,返回这个数组
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// 元素存放的数组
transient Object[] elementData;
// 元素的个数
private int size;

// 记录被修改的次数
protected transient int modCount = 0;
// 数组的最大值
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8

ArrayList有三个构造方法,不同的构造方法的容量是不一样的,具体可以查看JDK 源码。

  • 如果不传入初始容量,就使用默认容量,并设置 elementDataDEFAULTCAPACITY_EMPTY_ELEMENTDATA
  • 如果传入初始容量,会判断这个传入的值,如果大于0,就 new一个新的Object数组,如果等于0,就直接设置 elementDataEMPTY_ELEMENTDATA
  • 如果传入一个 Collection,则会调用toArray()方法把它变成一个数组并赋值给elementData。同样会判断它的长度是否为0,如果为0,设置elementDataEMPTY_ELEMENTDATA
3. ArrayList 的扩容具体指什么

ArrayList里面有两个概念,一个是capacity,它表示的就是“容量”,其实质是数组elementData的长度。而size则表示的“存放的元素的个数”。
因为 Java 中,数组操作不能越界,所以我们必须要保证在插入操作的时候,不会抛出数组越界异常。

4. ArrayList是如何实现扩容的?

扩容主要分两种,自动扩容和手动扩容。
自动扩容底层主要是三个私有方法:

// 扩容一个
private Object[] grow() {
	return grow(size + 1);
}

// 保证扩容到期望容量minCapacity及以上
private Object[] grow(int minCapacity) {
    return elementData = Arrays.copyOf(elementData,
                                       newCapacity(minCapacity));
}

// 根据期望容量minCapacity计算实际需要扩容的容量
private int newCapacity(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length; // 得到旧容量
    int newCapacity = oldCapacity + (oldCapacity >> 1); // 设置新容量为旧容量的1.5倍
    if (newCapacity - minCapacity <= 0) { // 如果新容量仍然小于期望容量
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // 如果是使用的默认容量
            return Math.max(DEFAULT_CAPACITY, minCapacity); // 取默认容量和期望容量较大值返回
        if (minCapacity < 0) // overflow // 检查期望容量是否越界(int 的范围)
            throw new OutOfMemoryError();
        return minCapacity; // 返回期望容量
    }
    // 如果新容量大于期望容量,判断一下新容量是否越界
    return (newCapacity - MAX_ARRAY_SIZE <= 0)
        ? newCapacity
        : hugeCapacity(minCapacity);
}

可以看到,底层其实是调用了Arrays.copyOf方法来进行扩充数组容量的。这里我们主要看一下最后一个方法newCapacity(int minCapacity)的实现。
默认情况下,新的容量会是原容量的1.5倍,这里用了位运算提高效率。一般情况下,如果扩容1.5倍后就大于期望容量,那就返回这个1.5倍旧容量的值。而如果小于期望容量,那就返回期望容量。这里对默认容量10做了特殊处理。
使用1.5倍这个数值而不是直接使用期望容量,是为了防止频繁扩容影响性能。试想如果每次add操作都要扩容一次,那性能将会非常低下。
手动扩容主要是一个公有方法ensureCapacity

public void ensureCapacity(int minCapacity) {
    if (minCapacity > elementData.length
        && !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
             && minCapacity <= DEFAULT_CAPACITY)) {
        modCount++;
        grow(minCapacity);
    }
}

5. ArrayList有缩容吗?

ArrayList没有缩容。无论是remove方法还是clear方法,它们都不会改变现有数组elementData的长度。但是它们都会把相应位置的元素设置为null,以便垃圾收集器回收掉不使用的元素,节省内存。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

类的加载,反射和注解详解

文章目录 类的加载概述类加载器作用分类获取类加载器的方式 双亲委派机制3种加载器的关系工作机制 类加载器的应用 反射概述关键获取类对象获取构造器对象获取方法对象获取成员变量对象作用 注解概述作用自定义注解格式属性类型 元注解常见的元注解 注解解析概述方法技巧 类的加…

Qt学习记录(C++)——Day 3

目录 一、封装自定义控件 1.添加界面类 2.添加控件 3.提升封装的控件 4.实现功能 5.提供接口 6.测试接口 二、鼠标事件 前言&#xff1a; 1.鼠标进入事件 enterEvent 2.鼠标离开事件 leaveEvent 3.鼠标按下事件 mousePressEvent 4.鼠标释放事件 mouseReleaseEv…

知识跟踪模型GraphKT

1 知识跟踪Knowledge Tracing的概念 知识跟踪可以用来解决自适应学习问题。如何通过与教学材料的在线互动来有效地跟踪学生的学习进展&#xff1f;知识跟踪可用于量化学生的知识状态&#xff0c;即对教材所涉及的技能掌握水平。用于评估和模拟学生随着时间推移对技能的认知掌握…

不借助第三方工具打包QT程序

准备工作&#xff1a; 项目/可执行文件名&#xff1a;QTAppName 打包项目存放的文件名&#xff1a;pack&#xff08;这个文件名无所谓&#xff09; 脚本名&#xff1a; copylib.sh&#xff08;类似ldd命令&#xff09;&#xff1a;用于将.so库文件的依赖项复制并放入自动生…

docker拉取镜像速度慢

解决办法是配置阿里云镜像加速 在docker desktop的docker engine里添加 "registry-mirrors": ["https://owzy8hoh.mirror.aliyuncs.com"] 修改以后重启docker 参考&#xff1a; 【docker】Windows10系统下安装并配置阿里云镜像加速_docker desktop 配置…

Steam平台FPS游戏节来袭,速来免费领取头像、边框和贴纸

首先&#xff0c;活动时间从4月16日持续到4月23日&#xff0c;想领取免费物品的小伙伴们要抓紧时间啦&#xff01;领取链接就在传送门等你哦。《战地》和《使命召唤》系列没有打折哦&#xff0c;有点遗憾。不过&#xff0c;别灰心&#xff0c;这次活动还是很给力的哦&#xff0…

Hyperledger Fabric

一.Hyperledger Fabric介绍 Hyperledger区块链全家桶 Hyperledger Fabric技术特性 资产 — 资产定义使得几乎任何具有货币价值的东西都可以在网络上交 换&#xff0c;包括从食品到古董汽车再到货币期货。链码 — 链码执行与交易排序的分离&#xff0c;限制了跨节点类型所需的…

Hibernate框架

什么是Hibernate 我们可以从度娘上摘抄这样有关Hibernate的介绍&#xff1a; Hibernate是一个开放源代码的对象关系映射框架&#xff0c;它对JDBC进行了非常轻量级的对象封装&#xff0c;它将POJO(简单java对象)与数据库表建立映射关系&#xff0c;是一个全自动的orm框架&…

【nnUNetv2进阶】四、nnUNetv2 魔改网络-小试牛刀-加入注意力机制ChannelAttention

nnUNet是一个自适应的深度学习框架&#xff0c;专为医学图像分割任务设计。以下是关于nnUNet的详细解释和特点&#xff1a; 自适应框架&#xff1a;nnUNet能够根据具体的医学图像分割任务自动调整模型结构、训练参数等&#xff0c;从而避免了繁琐的手工调参过程。 自动化流程&a…

LeetCode 80—— 删除有序数组中的重复项 II

阅读目录 1. 题目2. 解题思路3. 代码实现 1. 题目 2. 解题思路 让 index指向删除重复元素后数组的新长度&#xff1b;让 st_idx 指向重复元素的起始位置&#xff0c;而 i 指向重复元素的结束位置&#xff0c;duplicate_num代表重复元素的个数&#xff1b;一段重复元素结束后&am…

入侵检测数据预处理 特征工程 面临的问题

数据预处理 对于分类任务来说,由于原始数据可能存在异常、缺失值以及不同特征的取值范围差 异大等问题,对机器学习会产生影响,因此,在进行机器学习模型训练之前,需要先对数据 进行预处理。数据预处理的主要过程包括数据清洗、去量纲、离散化等。 1.数据清洗 对采集到的数据进行…

如何制作文字gif图?一键快速生成gif闪图

大家在聊天的过程中少不了使用gif表情包&#xff0c;但是大家知道这些gif动图怎么制作的吗&#xff1f;下面就来跟大家分享一下gif动图是如何制作的吧&#xff01;其实&#xff0c;非常的简单无需下载软件只需要使用gif图片制作&#xff08;https://www.gif5.net/&#xff09;工…

QT creator 代码中有中文,提示常量中有换行符解决方案

QT creator 代码中有中文&#xff0c;提示常量中有换行符解决方案 参考视频问题问题解决 参考 感谢感谢,非常感谢,有你,让Qt不再困难,困扰我四年的问题解决了!!! https://blog.csdn.net/m0_45866718/article/details/112389513 视频 https://www.bilibili.com/video/BV1Fp4…

GitHub提交PR

本教程只做开源代码库Github工程提交pr的教程&#xff0c;不做其他的深入的讲解 Github和Gitlab的操作类似&#xff0c;只不过Github叫PR&#xff0c;GitLab叫MR&#xff0c;基本上做法是一致的 以开源项目QuickChat为例 https://github.com/Binx98/QuickChat https://github…

CAN网络管理(网络节点)

什么是CAN的网络节点 网络节点是指连接到CAN总线上的设备或模块,每个网络节点都具有唯一的标识符,称为节点ID,用于在CAN总线上进行通信和识别。 如何判断CAN的网络节点是多少 可以根据DBC来定义查看, 以ADCU为例,域控作为主节点,一般外部的像雷达,camera的数据都是向…

Yolo-world使用

1、安装 python pip install ultralytics 前往官网下载模型&#xff1a;https://docs.ultralytics.com/models/yolo-world/#key-features 我这里使用yolov8s-world.pt举例 最简单的使用示例 if __name__ __main__:model YOLO(model/yolov8s-world.pt)results model.pre…

JCVI-筛选blast最佳结果(生物信息学工具-015)

通常&#xff0c;大家会问我们经过了NR注释&#xff0c;SwissProt注释&#xff0c;那么如何进行&#xff0c;如何挑选最佳比对结果&#xff1f; 同理&#xff0c;存在一个问题&#xff0c;如何挑选最佳的blast比对结果&#xff1f;什么事最优的同源序列&#xff1f; 唐海宝老…

DBUtils工具类的使用

1、DBUtils是什么 为了更加简单地使用JDBC&#xff0c;Apache组织提供了一个DBUtils工具&#xff0c;它是操作数据库的一个组件&#xff0c;实现了对JDBC的简单封装&#xff0c;可以在不影响数据库访问性能的情况下简化JDBC的编码工作量。DBUtils工具要有2个作用。 写数据&am…

力扣周赛392复盘

3105. 最长的严格递增或递减子数组 题目 给你一个整数数组 nums 。 返回数组 nums 中 严格递增 或 严格递减 的最长非空子数组的长度。 思考&#xff1a; 返回什么&#xff1a;返回最长非空子数组的长度。return max(decs_len,incs_len); 但实际上我们只需要用一个变量ans就…

记录PS学习查漏补缺

PS学习 PS学习理论快捷键抠图PS专属多软件通用快捷键 PS学习 理论 JPEG &#xff08;不带透明通道&#xff09; PNG (带透明通道) 快捷键 抠图 抠图方式 魔棒工具 反选选中区域 CtrlShiftI&#xff08;反选&#xff09; 钢笔抠图注意事项 按着Ctrl单击节点 会出现当前节…
最新文章