源码第一节:ArrayList-----出发了,新手村(集合篇)

本文详细介绍了ArrayList的底层实现,包括其动态数组的特性、默认初始容量、扩容策略、线程安全性等关键知识点。通过实例解析新增和删除元素的细节,帮助读者理解ArrayList的性能特点。学习源码旨在提升编程技能,将枯燥的知识转化为乐趣。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自我介绍篇

大家好,我是你们的会飞翔的蜗牛。看源码,就像打怪升级,作为我开始作为新手练级的一个boss就是ArrayList。那么出发打怪咯。

第一个BOSS

俗话说,知已知彼,方能百战不殆。那么我们先来了解下BOSS吧。它底层其实也是一个数组,所以我们也经常叫它动态数组。如果你看过我第一章节,你应该知道我在源码杂谈中,其实已经总结了学习源码集合的经验。我总结了所有源码集合中的共性的一些特性,并最终提炼出一些学习的方法。

装备自己

集合的共有特性有哪些?
1,组成集合最简单的数据结构是哪些?
2,集合默认初始化的长度是多少?
3,集合是否显示设置了扩容的因子?如果没设置?那么扩容因子多大?
4,集合的扩容最大值设置了多少?
5,集合的增删改查的细节了解多少?
6,集合扩容的条件是什么?怎么进行扩容的?有哪些细节需要注意的?
7,集合的查询的时间复杂度?新增元素的时间复杂度?
8,集合创建的时机,是new生成,还是add得时候生成?
9,集合是否线程安全?如果不是,如果保证线程安全?如果是,基于怎么样的原理?
10,相比较其他集合,它有什么优点和缺点?
说了这么多,我觉得你已经开始头晕了,没错,我只是列举了一些问题,希望你能带着这些问题,开始去看源码,而不是无头苍蝇一般这里看点,那里看点,最后不知道自己是否真的理解了集合。

打怪升级

学习本身就是一件枯燥得事情。如果你能把源码学习,学出乐趣出来。那么生活真的很精彩。好像在夸自己一样,O(∩_∩)O。
争对上面得问题,我们怎么去攻克我们得第一关得BOSS

1,ArrayList底层是一个数组。不信你看

private static final Object[] EMPTY_ELEMENTDATA = {};
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
transient Object[] elementData

ps:说好不贴代码的,男人的嘴骗人的鬼,哈哈,为了节省你找代码的时间。O(∩_∩)O。

2,ArrayList的默认初始长度是10。

private static final int DEFAULT_CAPACITY = 10;

3,ArrayList的扩容因子是1.5倍。并没有显示得设置一个属性,而从代码出能看出来。

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        //扩容成原来的1.5倍大小
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

4,ArrayList的最大值

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

5,集合的增删改查
这里不细细地讲了,但是对于新增和删除地某些细节,我这里特别指出来。

  • 新增元素。add地时候会先去判断整个集合是否已经塞不下元素了。那么就可以开始扩容了。那么可能出现两种情况,如果没有超出最大值,那么按照之前讲的,把集合大小扩容到1.5倍。如果超出了最大值,那么抛出异常。
  • 删除元素。删除元素有一个细节很重要。删除元素主要是调用了下面一个方法。
System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
// clear to let GC do its work(翻译:让GC去回收掉内存)
elementData[--size] = null; 

arracycopy大体可以理解为,把删除元素的索引为起点,右边的所有元素往左平移一格。最后的元素赋值为null,便于gc回收。
集合的删除的示意图
总结:

  1. ArrayList是动态数组。
  2. 默认初始长度为10,容量不够,每次以1.5倍增长。
  3. 线程不安全。
  4. 在new的时候创建一个空数组。当第一次add的时候,会设置长度为默认长度10。
  5. 在尾部删除,增加元素的时间复杂度为O(1)。在中间删除,增加元素的时间复杂度为O(n)。随机查询的时间复杂度为O(1)。

好了,今天的分享就到此结束了,感谢各位大佬的围观,我尽量增加趣味性地去讲清楚ArrayList底层实现。但是学习总是枯燥地,任何思考,都需要抛开娱乐,静下心来。就好像得道高僧,总是要放下执念,才能遁入佛道。高僧–>和尚–>秃头–>程序猿,O(∩_∩)O

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值