史上最全的Java容器集合之ArrayList(源码解读)(上)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 前言文本已收录至我的GitHub仓库,欢迎Star:github.com/bin39232820…种一棵树最好的时间是十年前,其次是现在

絮叨


前面2篇的基础,大家还是好好学习一下,下面是链接

🔥史上最全的Java容器集合之入门

🔥史上最全的Java容器集合之基础数据结构(手撕链表)

本来想直接将List这个父类下的所有之类,但是怕太长,我把我们真实开发中最最常用的ArrayList单独拿出来讲了,后面2个做一篇(顺便提一下,如果是零基础的不建议来,有过半年工作经验的跟着我一起把这些过一遍的话,对你的帮助是非常大的)

一、ArrayList认识


概念

概念:ArrayList是一个其容量能够动态增长的动态数组。但是他又和数组不一样,下面会分析对比。它继承了AbstractList,实现了List、RandomAccess, Cloneable, java.io.Serializable。

RandomAccess接口,被List实现之后,为List提供了随机访问功能,也就是通过下标获取元素对象的功能。

实现了Cloneable, java.io.Serializable意味着可以被克隆和序列化。

最主要的还是看我化圈的部分


ArrayList的数据结构

分析一个类的时候,数据结构往往是它的灵魂所在,理解底层的数据结构其实就理解了该类的实现思路,具体的实现细节再具体分析。

  ArrayList的数据结构是:    说明:底层的数据结构就是数组,数组元素类型为Object类型,即可以存放所有类型数据。我们对ArrayList类的实例的所有的操作底层都是基于数组的。


ArrayList源码分析


继承结构和层次关系


我们看一下ArrayList的继承结构:

- ArrayList extends AbstractList
- AbstractList extends AbstractCollection 
复制代码


所有类都继承Object  所以ArrayList的继承结构就是上图这样

思考 为什么要先继承AbstractList,而让AbstractList先实现List?而不是让ArrayList直接实现List?

这里是有一个思想,接口中全都是抽象的方法,而抽象类中可以有抽象方法,还可以有具体的实现方法,正是利用了这一点,让AbstractList是实现接口中一些通用的方法,而具体的类, 如ArrayList就继承这个AbstractList类,拿到一些通用的方法,然后自己在实现一些自己特有的方法,这样一来,让代码更简洁,就继承结构最底层的类中通用的方法都抽取出来,先一起实现了,减少重复代码。所以一般看到一个类上面还有一个抽象类,应该就是这个作用


RandomAccess这个接口

我点进去源码发现他是一个空的接口,为啥是个空接口呢

RandomAccess接口是一个标志接口(Marker)

ArrayList集合实现这个接口,就能支持快速随机访问


public static <T>
    int binarySearch(List<? extends Comparable<? super T>> list, T key) {
        if (list instanceof RandomAccess || list.size()<BINARYSEARCH_THRESHOLD)
            return Collections.indexedBinarySearch(list, key);
        else
            return Collections.iteratorBinarySearch(list, key);
    } 
复制代码


通过查看源代码,发现实现RandomAccess接口的List集合采用一般的for循环遍历,而未实现这接口则采用迭代器。

ArrayList用for循环遍历比iterator迭代器遍历快,LinkedList用iterator迭代器遍历比for循环遍历快, 所以说,当我们在做项目时,应该考虑到List集合的不同子类采用不同的遍历方式,能够提高性能! 然而有人发出疑问了,那怎么判断出接收的List子类是ArrayList还是LinkedList呢? 这时就需要用instanceof来判断List集合子类是否实现RandomAccess接口!


总结:RandomAccess接口这个空架子的存在,是为了能够更好地判断集合是否ArrayList或者LinkedList,从而能够更好选择更优的遍历方式,提高性能


ArrayList 类中的属性


public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    // 版本号
    private static final long serialVersionUID = 8683452581122892189L;
    // 缺省容量
    private static final int DEFAULT_CAPACITY = 10;
    // 空对象数组
    private static final Object[] EMPTY_ELEMENTDATA = {};
    // 缺省空对象数组
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    // 元素数组  ArrayList中有扩容这么一个概念,正因为它扩容,所以它能够实现“动态”增长
    transient Object[] elementData;
    // 实际元素大小,默认为0
    private int size;
    // 最大数组容量
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
}
复制代码


构造方法



无参构造

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
复制代码


此时ArrayList的size为空,但是elementData的length为1。第一次添加时,容量变成初始容量大小10(默认无参构造的容量就是10)


int参数构造

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);
        }
    }
复制代码


这个比较简单 进来判断是否大于0,如果大于0 就创建一个传进来大小的一个数组, 如果为0就是空数组

collection参数构造函数


public ArrayList(Collection<? extends E> c) {
        // 指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排
        // 这里主要做了两步:1.把集合的元素copy到elementData中。2.更新size值。
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
复制代码


把集合的元素重新放到新的集合里面,然后更新实际容量的大小

相关文章
|
7天前
|
算法 Java 数据处理
Java集合框架的优缺点
Java集合框架的优缺点
|
8天前
|
人工智能 前端开发 Java
基于java和uniapp的即时聊天源码
基于java和uniapp的即时聊天源码
15 1
|
8天前
|
Java 计算机视觉
java实现人脸识别源码【含测试效果图】——前台页面层(login.jsp)
java实现人脸识别源码【含测试效果图】——前台页面层(login.jsp)
8 0
|
3天前
|
人工智能 监控 算法
java智慧城管源码 AI视频智能分析 可直接上项目
Java智慧城管源码实现AI视频智能分析,适用于直接部署项目。系统运用互联网、大数据、云计算和AI提升城市管理水平,采用“一级监督、二级指挥、四级联动”模式。功能涵盖AI智能检测(如占道广告、垃圾处理等)、执法办案、视频分析、统计分析及队伍管理等多个模块,利用深度学习优化城市管理自动化和智能化,提供决策支持。
99 3
java智慧城管源码 AI视频智能分析 可直接上项目
|
8天前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——实体层(User.java)
mybatis简单案例源码详细【注释全面】——实体层(User.java)
9 0
|
2天前
|
Java
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
【Java】如果一个集合中类型是String如何使用拉姆达表达式 进行Bigdecimal类型计算?
11 0
|
7天前
|
缓存 NoSQL Java
java中复杂业务情况下的集合操作(增减集合同步数据)
java中复杂业务情况下的集合操作(增减集合同步数据)
15 0
|
7天前
|
存储 Java
java中的集合
java中的集合
7 2
|
7天前
|
传感器 人工智能 数据可视化
Java智慧工地监管一体化云平台APP源码 SaaS模式
高支模监测:高支模立杆及倾斜角度,高支模立杆的荷载,架体的水平位移以及模板沉降情况,当检测数据超过预警值时,实时报警。
19 2
|
8天前
|
存储 安全 Java
基于Java的qq截图工具(毕业设计含源码)
基于Java的qq截图工具(毕业设计含源码)
25 0

相关产品

  • 容器镜像服务
  • 容器服务Kubernetes版