首页 > 编程语言 >手撕ArrayList底层源码

手撕ArrayList底层源码

时间:2023-06-21 19:04:18浏览次数:51  
标签:int MAX ArrayList elementData private minCapacity 源码 底层

public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
    //外部操作数
    protected transient int modCount = 0;//2
}
public class ArrayList<E> extends AbstractList<E> implements List<E>{
    //默认容量
    private static final int DEFAULT_CAPACITY = 10;
    //空内容的数组(长度为0的数组)
    private static final Object[] EMPTY_ELEMENTDATA = {};
	//默认容量空内容的数字(长度为0的数组)
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    //元素容器
    transient Object[] elementData;//new Object[10]{张三,李四,null,null,null,...}
    //元素个数
    private int size;//2
    //最大的数组长度
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
    
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    
    //initialCapacity - 100
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
    
    //e - 李四
    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }
    
    //minCapacity - 2
    private void ensureCapacityInternal(int minCapacity) {
        //使用无参构造创建对象,第一次添加元素时进入的判断
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //minCapacity - 10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
    
    //minCapacity - 2
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    
    //minCapacity - 10
    private void grow(int minCapacity) {
        //oldCapacity - 0
        int oldCapacity = elementData.length;
        //newCapacity - 0
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            //newCapacity - 10
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        
        //数组的扩容
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
    
    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }
}
ArrayList<String> list = new ArrayList<>();
//ArrayList<String> list = new ArrayList<>(10000);

list.add("张三");
list.add("李四");
list.add("王五");
list.add("赵六");
  1. ArrayList默认容量是多少?

10

  1. ArrayList的数据结构是什么?

Object类型的一维数组 -- --------Object[] elementData;

  1. ArrayList容器的最大容量是多少?

Integer.MAX_VALUE-8

  1. ArrayList容器的最大容量为什么是Integer.MAX_VALUE-8?

减8的位置是用于存储数组的头部信息

  1. 什么时候创建ArrayList集合直接指定初始化容量?

ArrayList list = new ArrayList<>(10000);

当你需要存储大量的数据时

因为使用无参构造创建ArrayList对象,默认容量为10,存储大量数据时会存在多次扩容的情况,扩容效率低。所以我们在存储大量数据时,使用有参构造直接设置ArrayList底层数组的大小,减少扩容次数,从而提高程序性能

  1. ArrayList的扩容机制?
    原来长度的1.5倍

如何看集合源码?

  1. 找场景
  2. 关注继承关系
  3. 关注成员属性
  4. 关注创建对象的过程
  5. 关注添加元素的过程(考虑是否扩容)

标签:int,MAX,ArrayList,elementData,private,minCapacity,源码,底层
From: https://blog.51cto.com/u_16154651/6530464

相关文章

  • LinkedList底层源码
    publicabstractclassAbstractList<E>extendsAbstractCollection<E>implementsList<E>{//外部操作数protectedtransientintmodCount=0;//0}publicabstractclassAbstractSequentialList<E>extendsAbstractList<E>{......
  • 手撕Vector底层源码
    publicabstractclassAbstractList<E>extendsAbstractCollection<E>implementsList<E>{//外部操作数protectedtransientintmodCount=0;}publicclassVector<E>extendsAbstractList<E>implementsList<E>{//元素......
  • CentOS7 源码编译安装 Python 3.8.10,开启 SSL 功能
    背景CentOS7自带的Python3,或者通过yum安装的Python3,可能会有无法使用ssl的问题:$python3Python3.8.10(default,Jun132023,14:51:15)[GCC11.2.120220127(RedHat11.2.1-9)]onlinuxType"help","copyright","credits"or"license&qu......
  • 直播平台搭建源码,uni中使用轮播图
    直播平台搭建源码,uni中使用轮播图 <swiperclass="swiper"style="height:90rpx;"circularvertical="true"   :autoplay="true":interval="3000":duration="1000"><swiper-itemv-for="(item,index)in......
  • [万神网络科技]Windows12网页版开源HTML源码
    Windows12网页版开源HTML源码源码介绍Windows12网页版是一个开源项目,使用标准网络技术,例如Html、CSS和Javascript,希望让用户在网络上预先体验Windows12因为这只是概念版,所以内容可能与Windows12正式版本不一致。源码截图下载地址:vx公众号:万神的小屋......
  • 租赁小程序成品|租赁小程序源码|人车网租赁功能
    租赁市场一直是人们比较关注的,有时候我们因为工作需要使用数码产品,但是直接购买并不划算,如果可以进行短期的租赁不仅能满足使用需求,还能节省资金,通过租赁小程序系统用户可以更便捷的选择自己想要租用的产品,而且还给商家和用户都提供了安全性和可靠性,那么租赁小程序成品包含哪些功能......
  • Spring源码核心剖析
    前言SpringAOP作为Spring最核心的能力之一,其重要性不言而喻。然后需要知道的是AOP并不只是Spring特有的功能,而是一种思想,一种通用的功能。而SpringAOP只是在AOP的基础上将能力集成到SpringIOC中,使其作为bean的一种,从而我们能够很方便的进行使用。一、SpringAOP的使用方式1.1使......
  • XXL-job开源框架相关的源码流程解析。
    XXL-job框架是一个分布式的定时任务框架。他简单快捷。配置方便。而且用途广泛。所以他的源码非常值得一看。对于我来说。其中其自写的RPC框架。以及处理发布多个定时任务的高并发处理。是我打开微服务的大门。这是一篇xxl-job源码的解析与流程分析。比较偏口语化。在这篇随笔中......
  • SLF4J门面日志框架源码探索
    1SLF4J介绍SLF4J即SimpleLoggingFacadeforJava,它提供了Java中所有日志框架的简单外观或抽象。因此,它使用户能够使用单个依赖项处理任何日志框架,例如:Log4j,Logback和JUL(java.util.logging)。通过在类路径中插入适当的jar文件(绑定),可以在部署时插入所需的日志框架。如果要更......
  • 大功率平衡车,扭扭车 图纸 源码 平衡车原理图 pcb 矢量源码非库函数, Bom清单 物料表等
    大功率平衡车,扭扭车图纸源码平衡车原理图pcb矢量源码非库函数,Bom清单物料表等资料。500W功率STM32主控陀螺仪可用于学习电机开发,平衡车独轮车项目开发。ID:452500609590448918......