手撕ArrayList底层,透彻分析源码

  

ArrayList概述

  

你好大家好,今天就来介绍一下ArrayList,说到ArrayList,很多人都知道它的底层是使用数组实现的,线程不安全的,说到它的特点,都会说查找快,增删慢,因为面试题大家都是这么背过来的。今天就来说说它的底层源码吧。

  

ArrayList更准确的说是动态数组去实现的,这里使用动态两字,是为了能够充分体现它的特点。

  

再者就是ArrayList不是线程安全的,所以效率比较高,但是否这个是绝对的呢?答案是否定的。

  

ArrayList底层源码

  
 <代码>公共类ArrayList扩展AbstractList
  实现List 
  

(1) ArrayList继承AbstractList抽象类,实现了RandomAccess,可克隆,可序列化的接口,RandomAccess使其拥有快速访问的能力。

  

(2)可克隆其实就是一个标记接口,只有实现这个接口后,然后在类中重写对象中克隆的方法,然后通过类调用克隆方法才能克隆成功,如果不实现这个接口,则会抛出CloneNotSupportedException(克隆不被支持)异常。

  

(3)序列化是序列化接口,支持序列化和反序列化。

  

(4) DEFAULT_CAPACITY是ArrayList默认的初始化集合的大小。

  

(5) EMPTY_ELEMENTDATA是一个空对象数组,用于空实例的共享空数组实例。

  

(6) DEFAULTCAPACITY_EMPTY_ELEMENTDATA是使用默认构造函数创建集合的时候使用该对象

  

(7) elementData用于存放当前数据的数组对象。

  

(8)大小是集合的大小。

  

(9)当集合中的元素超出数组规定的长度时,数组就会进行扩容操作,扩容操作就是ArrayList存储操作缓慢的原因,尤其是当数据量较大的时候,每次扩容消耗的时间会越来越多。

  

ArrayList的构造方法源码

  <编辑> ArrayList (int initialCapacity)   
 <代码>公共ArrayList (int initialCapacity) {
  
  如果(initialCapacity比;0){
  这一点。elementData=https://www.yisu.com/zixun/new对象(initialCapacity);
  }else if (initialCapacity==0) {
  这一点。elementData=EMPTY_ELEMENTDATA;
  其他}{
  把新IllegalArgumentException(“非法容量:”+ initialCapacity);
  }
  } 
  

(1)该构造函数很简单,直接判断传进来的数值大小,要是大于零,直接初始一个该长度的数组对象,并赋值给elementData,要是等于零,将空数组对象EMPTY_ELEMENTDATA赋给elementData,否则,直接抛出异常。

  

(2)该构造函数一般使用在要初始化一个比较大数据量的的集合的时候使用。

  <编辑> ArrayList()   
 <代码>公共ArrayList () {
  这一点。elementData=https://www.yisu.com/zixun/DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
  } 
  

(1)将DEFAULTCAPACITY_EMPTY_ELEMENTDATA空数组对象赋给elementData

  <编辑> ArrayList(集合c)   
 <代码>公共ArrayList (Collection<?E>延伸;c) {
  
  elementData=https://www.yisu.com/zixun/c.toArray ();
  
  如果((大?elementData.length) !=0) {
  如果(elementData.getClass () !=Object [] . class)
  elementData=数组。copyOf (elementData、大小、对象[]. class);
  其他}{
  这一点。elementData=EMPTY_ELEMENTDATA;
  }
  } 
  

<强>这里主要做了两件事:
(1)先将集合c转化为数组,然后赋值给elementData数组对象。

  

(2)然后判断面积和是否相等并且不等于0,是则执行数据的赋值并重新赋值给数组对象elementData,否则直接将空数组对象赋值给elementData。

  

ArrayList的方法源码分析

  <编辑> add()方法   
 <代码>公共逻辑加(E E) {
  ensureCapacityInternal(+ 1)大小;
  elementData(大小+ +)=e;
  返回true;
  } 
  

(1)执行ensureCapacityInternal方法,判断原有的数组对象是否需要扩容。

  

(2)将e对象添加到elementData数组对象中。

  

接下来我们来看看ensureCapacityInternal方法的源码。

  
 <代码>私人空ensureCapacityInternal (int minCapacity) {
  ensureExplicitCapacity (calculateCapacity (elementData minCapacity));
  }

手撕ArrayList底层,透彻分析源码