jdk1.8集合框架源码解析(四)ArrayList源码解析

ArrayList是我们日常开发中最常用的集合类甚至没有之一,了解其底层源码非常重要,以下源码基于

jdk1.8.0_144版本

一、ArrayList的数据结构

集合框架数据结构是其灵魂,理解数据结构才能更好理解ArrayList的实现思路。

ArrayList的数据结构如下:

 ArrayList其底层是一个动态数组,存储的元素是所有对象即Object,下面看ArrayList是如何实现动态数组的。

二、ArrayList的继承体系

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable

ArrayList实现了List接口、RandomAccess(可随机访问)、Cloneable(可拷贝)、Serializable(可序列化)。

继承了AbstractList

2.1 实现RandomAccess接口的作用:

RandomAccessList 实现所使用的标记接口,用来表明其支持快速(通常是固定时间)随机访问。此接口的主要目的是允许一般的算法更改其行为,从而在将其应用到随机或连续访问列表时能提供良好的性能。

将操作随机访问列表的最佳算法(如 ArrayList)应用到连续访问列表(如 LinkedList)时,可产生二次项的行为。如果将某个算法应用到连续访问列表,那么在应用可能提供较差性能的算法前,鼓励使用一般的列表算法检查给定列表是否为此接口的一个 instanceof,如果需要保证可接受的性能,还可以更改其行为。

现在已经认识到,随机和连续访问之间的区别通常是模糊的。例如,如果列表很大时,某些 List 实现提供渐进的线性访问时间,但实际上是固定的访问时间。这样的 List 实现通常应该实现此接口。实际经验证明,如果是下列情况,则 List 实现应该实现此接口,即对于典型的类实例而言,此循环:

     for (int i=0, n=list.size(); i < n; i++){
        list.get(i);
    }      

的运行速度要快于以下循环:

  for (Iterator i=list.iterator(); i.hasNext(); ){
    i.next();

 }       

2.2 实现Cloneable接口的作用:

此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。

如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。

按照惯例,实现此接口的类应该使用公共方法重写 Object.clone(它是受保护的)。请参阅 Object.clone(),以获得有关重写此方法的详细信息。

注意,此接口 包含 clone 方法。因此,因为某个对象实现了此接口就克隆它是不可能的。即使 clone 方法是反射性调用的,也无法保证它将获得成功。

2.3实现Serializable接口的作用:

类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,仅用于标识可序列化的语义。

三、ArrayList的field

 
    /**
     *
     * 为保证 serialVersionUID 值跨不同 java 编译器实现的一致性,序列化
     * 类必须声明一个明确的 serialVersionUID 值。
     * 还强烈建议使用 private 修饰符显示声明 serialVersionUID(如果可能),
     * 原因是这种声明仅应用于直接声明
     * 类 -- serialVersionUID 字段作为继承成员没有用处
     *
     */
    private static final long serialVersionUID = 8683452581122892189L;

    /**
     * 默认初始容量
     */
    private static final int DEFAULT_CAPACITY = 10;

    /**
     * 空的实例.
     */
    private static final Object[] EMPTY_ELEMENTDATA = {};

    /**
     * Shared empty array instance used for default sized empty instances. We
     * distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
     * first element is added.
     */
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

    // 元素数组
    transient Object[] elementData; // non-private to simplify nested class access

    //元素的个数
    private int size;
    
    //分配数组的最大值
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

elementData,类型为Object[]的数组,用于存放实际元素,并且被标记为transient,也就意味着在序列化的时候,此字段是不会被序列化的

protected transient int modCount = 0;

modCount 是从其父类继承来的,已从结构上修改 此列表的次数。

 

四、ArrayList的构造函数

  //构造一个空的list其size为DEFAULT_CAPACITY 10
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

    //构造一个空的list根据指定的size
    public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Ill
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值