ArrayList源码简单分析

ArrayList源码

类继承即是实现接口

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

    AbstractList:即ArrayList是Collection下的实现类,因AbstractList继承至Collection接口,提供了一些基本的方法如add,还有迭代器Iterator,子类可以重写。

  • 实现

    List:实现该接口,是为了代码语义化更清晰,反射能拿到实现的接口。PS:听大佬说的;

    RandomAccess:标志一个类可以随机访问(随机的索引访问),是一个标志接口(Marker);

    Cloneable:标记接口,表示该类可以重写Object中的clone方法;

    Serializable:标记接口,表示该类对象可以被序列化成流;

成员变量

  1. int DEFAULT_CAPACITY=10

    默认数组初始化容量

  2. Object[] EMPTY_ELEMENTDATA = {}

    用于创建实例的共享空数组实例

  3. Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}

    使用默认容量创建容量实例的数组实例

    区别:EMPTY_ELEMENTDATA 当创建实例是指定了容量或传入collection实例时使用该数组实例;DEFAULTCAPACITY_EMPTY_ELEMENTDATA 时不指定初始化容量是使用。

  4. Object[] elementData

    数组缓存区

  5. int size

    集合长度

构造函数

  1. 默认无参构造
public ArrayList() {  
      this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;  
     }
  1. 有参构造:

    • 指定数组初始容量:默认为10
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);  
      }  
     }
* 存入一个Collection实例
public ArrayList(Collection<? extends E> c) {  
      elementData = c.toArray();  
      if ((size = elementData.length) != 0) {  
      if (elementData.getClass() != Object[].class)  
      //数组复制  
      elementData = Arrays.copyOf(elementData, size, Object[].class);  
      } else {  
      this.elementData = EMPTY_ELEMENTDATA;  
      }  
     }

主要做是给数组缓存区初始化,如传的是collection实例则进行数组复制;

重要方法

  • 添加:add(E e)
 public boolean add(E e) {  
      ensureCapacityInternal(size + 1);  // Increments modCount!!  
      elementData[size++] = e;  
      return true;  
     }  
       
     //确定存入元素所需容量最小容量  
     private void ensureCapacityInternal(int minCapacity) {  
      if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {  
      //默认的10的容量,选最大的保证能存入数组  
      minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);  
      }  
      ensureExplicitCapacity(minCapacity);  
      }  
       
     //确定数组容量是否需要增加  
     private void ensureExplicitCapacity(int minCapacity) {  
      //用于迭代  
      modCount++;  
       
      // 是否需要增加容量  
      if (minCapacity - elementData.length > 0)  
      grow(minCapacity);  
      }  
       
     //增加数组长度  
     private void grow(int minCapacity) {  
      int oldCapacity = elementData.length;  
      //位运算,右移1位,相当于/2,即新数组长度=老数组长度 + (老数组长度/2)  
      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);  
      }

	//指定索引位置添加元素
	public void add(int index, E element) {
    	//检查是否角标越界
        rangeCheckForAdd(index);
	//确定存入元素所需容量最小容量
        ensureCapacityInternal(size + 1);  
       	System.arraycopy(elementData, index, elementData, index + 1,size - index);
        elementData[index] = element;
         size++;
  	}
  • addAll()
public boolean addAll(Collection<? extends E> c) {
    //将集合转为数组
    Object[] a = c.toArray();
    int numNew = a.length;
    //确定存入元素所需容量最小容量
    ensureCapacityInternal(size + numNew);  // Increments modCount
  	//数组复制  
    System.arraycopy(a, 0, elementData, size, numNew);
    size += numNew;
    return numNew != 0;
}
  • 删除:remove()
public E remove(int index) {
    	//检查是否角标越界
        rangeCheck(index);
		
        modCount++;
        //该索引位置的元素
    	E oldValue = elementData(index);
		//移除元素,数组大小也需改变,需要重新进行数组复制,保证集合大小是准确的
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,numMoved);
    	//最后索引元素置null,帮助GC
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }
  • 获取:get()
public E get(int index) {
    //检查是否索引越界
    rangeCheck(index);
	//从缓冲数组中索引拿元素
    return elementData(index);
}
  • 设置:set()
public E get(int index) {
    //检查是否索引越界
    rangeCheck(index);
	//从缓冲数组中索引拿元素
    return elementData(index);
}
  • 设置:set()
public E set(int index, E element) {
    //检查是否索引越界
    rangeCheck(index);
	//老元素
    E oldValue = elementData(index);
    //索引位置重新赋值
    elementData[index] = element;
    return oldValue;
}
  • 删除:remove()
public E remove(int index) {
   //检查是否索引越界
    rangeCheck(index);
	
    modCount++;
    //移除索引位置的元素
    E oldValue = elementData(index);
	//数组大小-1
    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

迭代器

  • 迭代器最顶层接口
public interface Iterator<E> {
 	//是否有下一元素
    boolean hasNext();

	//获得下一个元素
    E next();

 	//删除下一个元素
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }

   //对每个剩余元素执行给定的操作,直到所有元素都被遍历完或引发异常。
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            //每个元素要执行的,函数式编程
            action.accept(next());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值