当前位置:   article > 正文

【List集合】List接口源码解读一(ArrayList)

【List集合】List接口源码解读一(ArrayList)

目录

前言

1. List接口的基本信息

2. ArrayList

2.1.ArrayList 的基本信息

2.2. ArrayList 的构造方法

2.2.1 ArrayList 的构造方法一

2.2.2 ArrayList 的构造方法二

2.2.3 ArrayList 的构造方法三

 2.3 ArrayList 的扩容方式

总结


前言

        Java 语言由于其跨平台、社区良好等特性,在企业级应用、移动应用、互联网开发等领域广泛应用。今天,让我们来认识一下 java.util 包下的 ArrayList 集合框架


1. List接口的基本信息

根据源码所知:

代码文档的作者:乔什·布洛赫(Josh Bolch)和尼尔·盖夫特(Neal Gafter)

  • List 接口继承自Collection接口
  • List 的实现类:
  1. ArrayList
  2. LinkedList
  3. Vector
  • List 的抽象类:
  1. AbstractList
  2. AbstractSequentialList
  • 代码起始版本:Java 1.2

2. ArrayList

2.1.ArrayList 的基本信息

根据源码所知:

  •  ArrayList 继承自抽象类 AbstractList
  • ArrayList 实现的接口:
  1. List 接口:表示一个有序的集合
  2. RandomAccess:标记接口,用于标识支持高效随机访问的集合
  3. Cloneable:支持克隆(Clone)操作
  4. java.io.Serializable:可以将当前类的对象转换为字节序列,以便在网络传输和保存到文件

根据源码所知:

  • serialVersionUID :这是用于序列化和反序列化 ArrayList 对象时的版本号。当对 ArrayList 类进行修改时,需要更新该版本号,以确保序列化和反序列化的兼容性。
  • int DEFAULT_CAPACITY = 10:默认的初始容量值,表示当没有指定容量时,ArrayList 的初始容量为 10。
  • Object[ ] EMPTY_ELEMENTDATA = { }: 这是一个空的 Object 数组,用于表示空的 ArrayList 实例。
  • Object[ ] DEFAULTCAPACITY_ELEMENTDATA = { }: 这也是一个空的 Object 数组,与 EMPTY_ELEMENTDATA 不同之处在于,当第一个元素被添加时,如果 elementData 数组等于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA,它将会被扩容为默认容量 DEFAULT_CAPACITY。
  • transient Object [ ] elementData:存储 ArrayList 元素的数组缓冲区。ArrayList 的容量等于这个数组缓冲区的长度。当 elementData 等于 DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时,表示 ArrayList 是空的,并且当第一个元素被添加时,会将其扩容为默认容量。

2.2. ArrayList 的构造方法

2.2.1 ArrayList 的构造方法一

根据源码所知:

这个构造方法接受一个整型参数,其中 initialCapacity 表示初始化 ArrayList 的初始容量

  • 如果 initialCapacity 大于0,则初始化 elementData 数组为指定容量的 Object 数组。
  • 如果 initialCapacity 等于0,则将 elementData 数组初始化为空的常量EMPTY_ELEMENTDATA。
  • 如果 initialCapacity 小于0,则抛出 IllegalArgumentException 异常,提示传入的容量参数不合法。

2.2.2 ArrayList 的构造方法二

根据源码所知:

这是一个无参构造方法,用于构造一个空列表,初始容量为默认的大小。

  • 默认的空列表会将 elementData 数组初始化为DEFAULTCAPACITY_EMPTY_ELEMENTDATA。

2.2.3 ArrayList 的构造方法三

根据源码所知:

这个构造方法接受一个类型为Collection的参数c,用于构造一个包含指定集合元素的ArrayList。

  • 将集合c转换为数组,并赋值给 elementData。
  • 获取数组的长度作为列表的大小 size。
  • 如果数组的长度不为0,针对可能出现的类型转换问题进行处理,确保elementData是Object[] 类型。
  • 如果数组长度为0,将elementData初始化为空的常量EMPTY_ELEMENTDATA。

 2.3 ArrayList 的扩容方式

根据源码所知:

  • 当 ArrayList 需要进行扩容时,会调用 grow(int minCapacity)方法。这个方法会计算出新的容量值 newCapacity
  • 通常情况下,新容量值是旧容量的1.5倍(即 oldCapacity + (oldCapacity >> 1)
  • 接着会判断是否超出了最大数组容量(2^31 - 1 - 8),如果超出则调用 hugeCapacity 方法进行处理
  • 最后,通过调用 Arrays.copyOf 方法,将原数组的内容复制到新的具有更大容量的数组中,完成扩容操作

根据源码所知:

  • 当数组容量的新容量超出最大数组容量(2^31 - 1 - 8)时调用hugeCapacity 方法进行处理,如果需要的最小容量 minCapacity 小于 0,则会抛出 OutOfMemoryError 异常
  • 如果需要的最小容量 minCapacity 超出数组最大容量(2^31 - 1 - 8),则返回 2^31 - 1 给新容量,否则返回数组最大容量 2^31 - 1 -8 

总结

  • ArrayList 继承自 AbstractList 抽象类 

ArrayList 的应用场景:

  • ArrayList 的数据结构为 Object[ ] 数组,实现了 RandomAccess 接口,支持高效随机访问和克隆操作。适用于遍历、查找等读取数据元素的应用场景。
  • ArrayList 实现了 java.io.Serializable ,可以被序列化为字节序列,以便在网络传输和保存到文件

ArrayList 的扩容方式:

  1. 使用无参构造方法创建 ArrayList 时,实际上初始化赋值是一个空数组,当向数组中添加第一个元素时,数组容量扩容为10
  2. 当数组容量不足时,调用 grow() 方法进行扩容,每次扩容后容量会变为原来的 1.5 倍左右
  3. ArrayList 的最大容量为 2^31 - 1 或 2^31 -1 -8

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/255931
推荐阅读
相关标签
  

闽ICP备14008679号