ArrayList理解

ArrayList

实现List接口底层为数组,与java中数组相比容量可以动态增加
特点

  • 线程不安全
  • 元素有序
  • 插入元素可为null
  • 查询快,增删满

首先介绍两个常见的方法
Arrays.copyOf()
从源数组中获得指定长度的数组,返回一个新数组

//调用copyOf(T[] original, int newLength)时newType默认为original类型
public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) {
        @SuppressWarnings("unchecked")
        T[] copy = ((Object)newType == (Object)Object[].class)
            ? (T[]) new Object[newLength]
            : (T[]) Array.newInstance(newType.getComponentType(), newLength);

		//如果newLength比源数组长则新数组剩余值为类型默认值
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
}

System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

native方法,首先检查src、dest是否为数组类型,再判断是否越界,最后进行复制
复制数组src,以srcPos为起始位置(包括),长度为length的数据到dest数组以destPos为起始位置(包括)长度为length的位置

ArrayList类

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
	//默认初始容量
	private static final int DEFAULT_CAPACITY = 10;
	//空对象数组
	private static final Object[] EMPTY_ELEMENTDATA = {};
	//缺省空对象数组
	private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
	//存放当前集合中元素的数组
	transient Object[] elementData; 
	//当前集合大小
	private int size;
	
	//构造器,数组初始默认为空,开始添加时扩容为DEFAULT_CAPACITY 
	public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    //构造指定大小数组
    public ArrayList(int initialCapacity)

	//首先判断容量是否超出限制,在当前size+1添加元素
	public boolean add(E e) {
        ensureCapacityInternal(size + 1);  
        elementData[size++] = e;
        return true;
    }
    //扩容过程
    private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
    }
    //如果当前数组为空则返回Math.max(10,size+1)
    private static int calculateCapacity(Object[] elementData, int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(DEFAULT_CAPACITY, minCapacity);
        }
        return minCapacity;
    }
    //结构修改次数加1,判断容量是否超出限制,超出则调用grow
    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
    //新容量大小为old+old>>1,增加原容量的一半
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //初始时newCapacity为0,默认大小为minCapacity 10
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        //最大为Integer.MAX_VALUE
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //创建一个容量为newCapacity的新数组
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
	//指定位置添加,首先判断索引是否在数组长度范围内,然后确定容量是否充足
	public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  
        //将[index,size)复制到[index+1,size+1),相当于index之后(包括)数据都后移一位
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        //在index插入元素
        elementData[index] = element;
        size++;
    }

	//删除index位置的元素
	public E remove(int index) {
		//检查索引是否在数组范围内
        rangeCheck(index);
        //结构修改次数加1
        modCount++;
        //返回的删除值
        E oldValue = elementData(index);
        int numMoved = size - index - 1;
        if (numMoved > 0)
        	//将index之后的元素统一前移一位
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        //置为null,GC回收
        elementData[--size] = null; 
        return oldValue;
    }
	//for循环遍历equals比较 删除
	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;
    }
	
	//数组置null,size置0
	public void clear() {
        modCount++;
        for (int i = 0; i < size; i++)
            elementData[i] = null;
        size = 0;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值