Java基础集合---ArrayList

ArrayList源码解析

  • 简介

    ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。

    ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。

    ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现了Cloneable接口,能被克隆。

    *由add()方法中检查扩容操作可以看出:ArrayList初始化时最好指定可预测的数组长度,避免扩容导致系统消耗

  • 构造函数

/**
 Constructs an empty list with an initial capacity of ten.
构造初始容量为10的空列表。
*/
public ArrayList() {
  this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

/**
     * Constructs an empty list with the specified initial capacity.
     *用指定的初始容量构造空列表。
     * @param  initialCapacity  the initial capacity of the list
     初始容量列表的初始容量
     * @throws IllegalArgumentException if the specified initial capacity is negative
     指定的初始容量为负
     */
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);
        }
}

/**
     * Constructs a list containing the elements of the specified
     * collection, in the order they are returned by the collection's
     * iterator.
     *构造包含指定集合的元素的列表,按集合的迭代器返回这些元素的顺序
     * @param c the collection whose elements are to be placed into this list
     * @throws NullPointerException if the specified collection is null
     */
public ArrayList(Collection<? extends E> c) {
  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;
    }
}

  • 插入数据
/**
     * Appends the specified element to the end of this list.
     *将指定的元素追加到此列表的末尾。
     * @param e element to be appended to this list
     * @return <tt>true</tt> (as specified by {@link Collection#add})
     */
public boolean add(E e) {
  //检测是否扩容
  ensureCapacityInternal(size + 1);  // Increments modCount!!
  elementData[size++] = e;
  return true;
}

/**
     * Inserts the specified element at the specified position in this
     * list. Shifts the element currently at that position (if any) and
     * any subsequent elements to the right (adds one to their indices).
     *在此列表中的指定位置插入指定元素。将当前位于该位置的元素(如果有)和任何后续元素向右移动(将一				  个元素添加到其索引中)。
     * @param index index at which the specified element is to be inserted
     * @param element element to be inserted
     * @throws IndexOutOfBoundsException {@inheritDoc}
     */
public void add(int index, E element) {
  rangeCheckForAdd(index);

  ensureCapacityInternal(size + 1);  // Increments modCount!!
  System.arraycopy(elementData, index, elementData, index + 1,
                   size - index);
  elementData[index] = element;
  size++;
}
  • 扩容检查
 /**
 检查arrayList数组是否需要扩容
 */ 
 private void ensureCapacityInternal(int minCapacity) {
   //当前数组是否是空数组
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
      //空数组,返回默认长度
      minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    //检查扩容
    ensureExplicitCapacity(minCapacity);
  }

  private void ensureExplicitCapacity(int minCapacity) {
    //记录操作次数
    modCount++;

    // overflow-conscious code
    //如果长度-数组长度>0,进行扩容处理
    if (minCapacity - elementData.length > 0)
      grow(minCapacity);
  }
  /**
  * Increases the capacity to ensure that it can hold at least the
  * number of elements specified by the minimum capacity argument.
  *
  * @param minCapacity the desired minimum capacity
  */
  private void grow(int minCapacity) {
    // overflow-conscious code
    int oldCapacity = elementData.length;
    //新的数组长度 = 旧长度+旧长度*0.5(即:arrayList默认扩容1.5倍)
    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 E remove(int index) {
          //检查下标是否越界
            rangeCheck(index);
          //增加操作次数
            modCount++;
          //获取下标对应的元素
            E oldValue = elementData(index);
           //数据移动量
           //将index+1及之后的元素向前移动一位 
           //例: size =10 当前数组最大index =9
           //对应index为0,1,2,3,4,5,6,7,8,9
           //index =2 则需要将index为3,4,5,6,7,8,9的数据向前移动一位
        	 //即:对应的移动量为 size-index-1 =7
            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 boolean remove(Object o) {
          //判断元素是否为null 如果为null 则删除第一个为null的元素下标
            if (o == null) {
                for (int index = 0; index < size; index++)
                  //找出第一个为null的下标,根据下标进行删除
                    if (elementData[index] == null) {
                        fastRemove(index);
                        return true;
                    }
            } else {
                for (int index = 0; index < size; index++)
                  //找出第一个元素为o的下标,根据下标进行删除
                    if (o.equals(elementData[index])) {
                        fastRemove(index);
                        return true;
                    }
            }
            return false;
        }
    	private void fastRemove(int index) {
            modCount++;
            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
        }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值