Java ArrayList源码分析

Posted google12071

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java ArrayList源码分析相关的知识,希望对你有一定的参考价值。

ArrayList概述

   ArrayList是List接口最常用的实现类,底层由数组实现,可存入null值,每个ArrayList都有一个容量(capacity)属性,初始值是10,表示底层数组的存储空间,容器内当前元素个数大于数组存储容量时,ArrayList会自动完成容量扩增,因此我们在向ArrayList中添加元素时无需考虑容量,容器内部已经帮我们完成了容量扩容过程。

  技术分享图片

   ArrayList具有public ArrayList() ;public ArrayList(int initialCapacity);public ArrayList(Collection<? extends E> c)三个构造器,创建ArrayList时可以指定容量或选择用其他Collection为当前ArrayList赋值(底层采用数组复制的方式实现)或采用无参构造器创建默认容量的数组,size小于当前元素个数时,将自动完成容量扩充。

常用方法剖析

 add方法 

//添加元素至数组尾部
 public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 容量自增
        elementData[size++] = e;
        return true;
    }
//添加元素至制定位置(index)
 public void add(int index, E element) {
        rangeCheckForAdd(index);//检查容量
        ensureCapacityInternal(size + 1);  // 容量自增
        System.arraycopy(elementData, index, elementData, index + 1,size - index);//从index+1元素向后移动
        elementData[index] = element;//为新添加元素赋值
        size++;
    }
//插入复杂度与位置与移动元素个数有关,此方法具有线性的时间复杂度

 addAll方法

//添加多个元素至数组尾部
public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();//待添加集合转化为对象数组
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // 扩充容量
        System.arraycopy(a, 0, elementData, size, numNew);//数组复制
        size += numNew;
        return numNew != 0;
    }
//从指定位置添加多个元素
 public boolean addAll(int index, Collection<? extends E> c) {
        rangeCheckForAdd(index);
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacityInternal(size + numNew);  // 扩充容量
        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elementData, index, elementData, index + numNew,numMoved);//数组复制
        System.arraycopy(a, 0, elementData, index, numNew);
        size += numNew;
        return numNew != 0;
    }
//添加过程不光与元素个数有关与待添加位置也有关 

 reomve方法

//从指定为主删除元素并返回待删除元素
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);//数组向前移动
        elementData[--size] = null; // 为GC方便回收,将末尾置为null
        return oldValue;
    }
//删除原数组中与目标对象相同的元素
 public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

  set/get方法

//为指定位置元素赋值
 public E set(int index, E element) {
        rangeCheck(index);//检查数组状态
        E oldValue = elementData(index);//检查为否出现数组下标越界异常
        elementData[index] = element;//用新值替换原元素值
        return oldValue;//返回原元素值
 }
//获取某一元素的值
 public E get(int index) {
        rangeCheck(index);//检查为否出现数组下标越界异常
        return elementData(index);//返回索引位置的元素值
  }

   grow方法(实现自动容量扩充)

private void grow(int minCapacity) {
        int oldCapacity = elementData.length;//原容量
        int newCapacity = oldCapacity + (oldCapacity >> 1);//扩充为原容量1.5倍
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);//数组元素复制
  }

以上是关于Java ArrayList源码分析的主要内容,如果未能解决你的问题,请参考以下文章

ArrayList精讲(源码分析)---Java集合

Java中Arraylist源码分析

Java笔记---ArrayList源码分析

Java-ArrayList源码分析

[Java源码分析]ArrayList源码分析

Java中arraylist和linkedlist源码分析与性能比较