java入门--ArrayList源码简析

ArrayList继承了Abstract类实现了List、RandomAccess、Cloneable和Serializable接口。

1、ArrayList有三个构造方法:如下

public ArrayList(int initialCapacity) {
        super();//调用父类protected Abstractlist(){}
        if(initialCapacity <0) {
            throw new IllegalArgumentException("Illegal Capacity:" + initialCapacity);
        }
        this.elementData = new Object[initialCapacity];
    }
    public ArrayList() {
        this(10);//直接调用上一个public ArrayList(int initialCapacity){}初始化
    }
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        if(elementData.getClass() != Object[].class) {
            elementData = Arrays.copyOf(elementData,size,Object[].class);
        }
    }

第一个是带参的构造方法,直接调用父类AbstractList的构造方法,并且如果初始长度小于零则直接抛出异常,将一开始定义的Object[]数组进行一个长度初始化;第二个是无参的构造方法直接调用第一个的构造方法然后将elementData数组初始化长度为10的数组;第三个构造方法带有一个集合类型的参数,首先将集合类型数据通过toArray()方法转换成数组,然后将其赋给elementData。


2、add(E e)

public boolean add(E e) {
        ensureCapacity(size +1);
        elementData[size++] = e;
        return true;
    }

方法中首先是调用了ensureCapacity(size+1),然后是在elementData最后位置添加了element e 并且返回true。那么ensureCapacity是怎样的一个方法呢?


3、ensureCapacity(int minCapacity)方法

public void ensureCapacity(int minCapacity) {
        modCount++;
        int oldCapacity = elementData.length;
        //如果数组满了,又有新元素加入,执行扩容逻辑
        if(minCapacity > oldCapacity) {
            Object oldData[] = elementData;
            int newCapacity = (oldCapacity*3)/2+1;
            if(newCapacity < minCapacity) {
                newCapacity = minCapacity;
            }
            elementData = Arrays.copyOf(elementData,newCapacity);
        }
    }

从上面我们可以看到,在方法二中的调用了ensureCapacity(size+1)也就是此时的minCapacity就是size+1。首先对modCount计数,然后将当前的elementData数组的长度赋值给oldCapacity。此时我们就要比较minCapacity和oldCapacity哪个大,如果oldCapacity的长度(也就是当前elementData的长度)小于minCapacity(也就是size+1),那么此时我们就要对数组elementData进行一个扩容为原来长度的1.5倍长度+1。


4、add(int index,E e)返回类型为void类型

public void add(int index,E element) {
        if((index > size)||(index <0)){
            throw new IndexOutOfBoundsException("Index:"+index +"size"+size);
        }
        ensureCapacity(size+1);
        System.arraycopy(elementData, index,elementData, index+1,size-index);
        elementData[index] = element;
        size++;
    }

首先我们需要判断索引是否超出了当前的size或者index是否<0,如果是则马上抛出异常.因为此时要将内容插入,所以当前的长度要进行扩容,ensureCapacity(size+1)。扩容之后采用System.arraycopy(Object src,int srcPos,Object dest,int destPos,int length)方法将数组进行复制。从System.arraycopy方法中我们可以看到数组srcPos从src开始的元素复制到dest

import java.util.Collection;
import java.util.*;
public class ArrayList<E> extends AbstractList<E> implements List<E> ,RandomAccess,Cloneable,java.io.Serializable{
    private transient Object[] elementData;
    private int size;
    //构造方法
    public ArrayList(int initialCapacity) {
        super();//调用父类protected Abstractlist(){}
        if(initialCapacity <0) {
            throw new IllegalArgumentException("Illegal Capacity:" + initialCapacity);
        }
        this.elementData = new Object[initialCapacity];
    }
    public ArrayList() {
        this(10);//直接调用上一个public ArrayList(int initialCapacity){}初始化
    }
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        if(elementData.getClass() != Object[].class) {
            elementData = Arrays.copyOf(elementData,size,Object[].class);
        }
    }
    public boolean addAll(Collection<? extends E> c) {
        Object[] a = c.toArray();
        int numNew = a.length;
        ensureCapacity(size + numNew);
        System.arraycopy(a, 0, elementData, size, numNew);
        size += numNew;
        return numNew != 0;
    }

    public boolean add(E e) {
        ensureCapacity(size +1);
        elementData[size++] = e;
        return true;
    }

    public void ensureCapacity(int minCapacity) {
        modCount++;
        int oldCapacity = elementData.length;
        //如果数组满了,又有新元素加入,执行扩容逻辑
        if(minCapacity > oldCapacity) {
            Object oldData[] = elementData;
            int newCapacity = (oldCapacity*3)/2+1;
            if(newCapacity < minCapacity) {
                newCapacity = minCapacity;
            }
            elementData = Arrays.copyOf(elementData,newCapacity);
        }
    }
    public int size() {
        return size;
    }
    public Object[] toArray() {
        return Arrays.copyOf(elementData,size);
    }
    public <T> T[] toArray(T[] a) {
        if(a.length<size)
            return (T[]) Arrays.copyOf(elementData,size,a.getCalss());
        System.arraycopy(elementData, 0, a, 0, size);
        if(a.length>size)
            a[size] = null;
        return a;

    }
    public void add(int index,E element) {
        if((index > size)||(index <0)){
            throw new IndexOutOfBoundsException("Index:"+index +"size"+size);
        }
        elementData[index] = element;
        size++;
    }
    public  E set(int index,E element) {
        RangeCheck(index);
        E oldValue = (E) elementData[index];
        elementData[index] = element;
        return oldValue;
    }
    public E get(int index) {
        RangeCheck(index);
        return (E) elementData[index];
    }
    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;
    }
    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;
    }
    private void RangeCheck(int index) {
        if(index >= size)
            throw new IndexOutOfBoundsException("index:"+index+",Size:"+size);
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值