Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

这篇具有很好参考价值的文章主要介绍了Java 集合中 ArrayList 的扩容机制原理(面试+读源码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

           在 Java 中,ArrayList 内部是通过一个数组来存储元素的,是一个数组结构的存储容器。当向一个 ArrayList 中添加元素时,如果当前数组已经满了,就需要扩容。 

       Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

集合的继承关系图 

一、面试回答

( ArrayList 的扩容机制原理 ) 

        面试官好,ArrayList 是一个数组结构的存储容器,默认情况下,设置数组长度是 10. 当然我们也可以在构建 ArrayList 对象的时候自己指定初始长度。 随着在程序里面不断的往 ArrayList 中添加数据,当添加的数据达到 10 个的时候, ArrayList 就没有多余容量可以存储后续的数据。 这个时候 ArrayList 会自动触发扩容。 扩容的具体流程很简单, 1. 首先,创建一个新的数组,这个新数组的长度是原来数组长度的 1.5 倍。 2. 然后使用 Arrays.copyOf 方法把老数组里面的数据拷贝到新的数组里面。 扩容完成后再把当前要添加的元素加入到新的数组里面,从而完成动态扩容的过程。 以上就是我对这个我对这个问题的理解! 

或者不直接问: ArrayList 扩容是在第10个元素还是第11个元素触发的 ?

        在 Java 中,ArrayList 的扩容是在添加第11个元素时触发的,当 ArrayList 中的元素数量达到了其初始容量(默认为 10)时,ArrayList 会自动扩容,新的容量为原来的 1.5 倍。当然也可以在创建 ArrayList 对象时指定其初始容量,以避免频繁的扩容操作。

二、源码理解(Debug模式)

import java.util.ArrayList;
@SuppressWarnings({"all"})
public class ArrayListSource {

    public static void main(String[] args) {

        //解读源码
        //注意,注意,注意,Idea 默认情况下,Debug 显示的数据是简化后的,如果希望看到完整的数据
        //需要做设置. //使用无参构造器创建 ArrayList 对象
        ArrayList list = new ArrayList();
//        ArrayList list = new ArrayList(8);
        //使用 for 给 list 集合添加 1-10 数据
        for (int i = 1; i <= 10; i++) {
            list.add(i);
        }
        //使用 for 给 list 集合添加 11-15 数据
        for (int i = 11; i <= 15; i++) {
            list.add(i);
        }
        list.add(100);
        list.add(200);
        list.add(null);
    }
}
F7  单步调试进行下一步,遇到方法会进入方法内,同一行有多个方法时可以用左右键选择;
F8  单步调试,进行下一步,不会进入方法内;
Alt+Shift+F7 强制进入方法内;
Shift+F8   直接跳出方法;
F9 跳到下一个断点或者直接执行完程序

Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

 

首先进入ArrayList的构造器,看到  elementData 第一次初始化的时候就是一个空数组

Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

接下来进入到for循环,第一次进去会把int 给类型转化,进行一个装箱操作。 

 Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

然后在添加的时候 ,先执行了判断这个要添加的这个 e 的大小是否达到要求,满足了再将e放入Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

 Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

 第一次返回的一定是 10 (是规定好的了)Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

 

拿到 minCapacity 然后再进入到  ensureExplicitCapacity 其中modCount 表示被修改的次数(这里主要防止有多个线程同时去修改,如果有,则会抛出异常)

 Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

只有当  elementData 的大小小于10的时候就调用grow 方法进行扩容。

 Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

 先把传进来的数组大小赋值给一个变量 oldCapacity ,然后按照原先数组的1.5倍进行扩容(右移一位,相当于除以2) 而 Arrays.copyOf 其实就是数组的复制。

Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

即得到了 10个 elementData 的空元素

Java 集合中 ArrayList 的扩容机制原理(面试+读源码)

 

ArrayList 的扩容机制是在添加元素时判断当前数组大小是否已经满了,如果已经满了,则创建一个新的更大的数组,并将原来的元素全部复制到新的数组中。具体的扩容规则如下:

  1. 当添加元素后,size 大小已经等于或超过了数组的容量 capacity 时,就会触发扩容操作。
  2. 扩容的大小默认情况下为原数组大小的一半。比如原数组大小为 10,那么扩容后的数组大小为 15。
  3. 如果扩容后的大小还是不够,那么就以添加元素的数量作为扩容大小,即新数组的大小为 oldCapacity + (oldCapacity >> 1) + 1。

        需要注意的是,ArrayList 中的数组无法动态地调整大小,因此每次扩容都需要创建新的数组和复制元素,这可能会带来一些性能损失。为了避免频繁扩容,我们可以在使用 ArrayList 时尽量预估元素数量,初始化时指定一个合适的初始容量。

在实际使用中,我们可以通过指定初始容量和适当的预估来优化扩容操作,以提高性能。文章来源地址https://www.toymoban.com/news/detail-469135.html

到了这里,关于Java 集合中 ArrayList 的扩容机制原理(面试+读源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ArrayList 扩容机制

    ArrayList 实现了 List 接口。它可以存储包括 null 的任何类型的对象,允许重复元素。 ArrayList 在内部使用一个数组来存储元素,当元素数量超过数组容量时, ArrayList 会自动重新分配更大的内部数组,并且将现有元素复制到新数组中。 ArrayList 基本等同于 Vector ,但是 ArrayList 是

    2024年02月08日
    浏览(9)
  • Java集合框架之ArrayList源码分析

    ArrayList是Java提供的线性集合,本篇笔记将从源码(java SE 17)的角度学习ArrayList: 什么是ArrayList? ArrayList底层数据结构是怎么实现的? 作为一个容器,分析增删改查的过程 ArrayList的扩容机制 由ArrayList的定义可知,ArrayList继承了AbstractList抽象类,实现了List、RandomAccess、Cloneabl

    2024年02月07日
    浏览(25)
  • Java:ArrayList集合、LinkedList(链表)集合的底层原理及应用场景

    入队 出队 压栈(push),addFirst可以替换成push,官方专门为压栈写了push的API 出栈(pop),removeFirst可以替换成pop,官方专门为出栈写了pop的API

    2024年02月12日
    浏览(17)
  • java源码----集合系列1----ArrayList,linkedList

    底层是一个object数组 Arraylist 是java里面Collection  标准的一个集合,其 底层是一个object数组 。当new一个空参的ArrayList的时候,会默认生成一个空数组。 Arraylist上限是 Integer.MAX_VALUE - 8(Integer.MAX_VALUE  =  2^31-1) ; 超过上限会报内存溢出 这里为什么是Integer.MAX_VALUE-8  ,源码上的解

    2024年02月03日
    浏览(14)
  • 【Java集合类面试二十六】、介绍一下ArrayList的数据结构?

    文章底部有个人公众号: 热爱技术的小郑 。主要分享开发知识、学习资料、毕业设计指导等。有兴趣的可以关注一下。为何分享? 踩过的坑没必要让别人在再踩,自己复盘也能加深记忆。利己利人、所谓双赢。 面试官:介绍一下ArrayList的数据结构? 参考答案: ArrayList的底

    2024年02月08日
    浏览(15)
  • 深入源码解析ArrayList:探秘Java动态数组的机制与性能

    1.1 介绍ArrayList的基本概念和作用 在Java中,ArrayList是一个实现了List接口的动态数组。它可以根据需要自动增加大小,因此可以存储任意数量的元素。 基本概念: ArrayList是Java中常用的集合类之一,它可以存储对象,并且可以根据索引访问和操作这些对象。 ArrayList是基于数组

    2024年02月04日
    浏览(11)
  • ArrayList集合源码阅读

    ArrayList 是 Java 中的一种集合(Collection)类,它可以用来存储一组对象。下面是一些 ArrayList 的重要知识点: ArrayList 是动态数组,它的大小可以根据需要自动增长或缩小。 ArrayList 是通过数组实现的,每个元素可以通过其索引进行访问。 ArrayList 可以存储任意类型的对象,包括

    2023年04月25日
    浏览(18)
  • 探索Java集合框架—数据结构、ArrayList集合

    Java集合的使用相信大家都已经非常得心应手,但是我们怎么做到知其然,更知其所以然这种出神入化的境界呢?我们揭开集合框架底层神秘面纱来一探究竟 目录 一、背景介绍 二、思路方案 数据结构是什么? 数据结构可以分为线性和非线性两种数据结构 线性数据结构: 非

    2024年02月10日
    浏览(16)
  • Java集合之ArrayList详解

    1.1. Iterator:提供了一种方便、安全、高效的遍历方式。 Iterator是一个迭代器接口,它提供了一种安全的遍历集合元素的方法,可以避免在遍历过程中修改集合引起的ConcurrentModificationException异常,同时还可以避免在遍历过程中删除集合元素时出现索引越界等问题。 ArrayList使用

    2024年02月10日
    浏览(13)
  • 【Java】ArrayList(集合)超详解

    集合和数组的优势对比: 长度可变 添加数据的时候不需要考虑索引,默认将数据添加到末尾 1.1ArrayList类概述 什么是集合 ​ 提供一种存储空间可变的存储模型,存储的数据容量可以发生改变 ArrayList集合的特点 ​ 底层是数组实现的,长度可以变化 泛型的使用 ​ 用于约束集

    2023年04月20日
    浏览(19)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包