【java基础】ArrayList源码解析

ArrayList底层是用数组实现的。

private static final long serialVersionUID = 8683452581122892189L;

    //默认初始容量
    private static final int DEFAULT_CAPACITY = 10;

    //空数组
    private static final Object[] EMPTY_ELEMENTDATA = {};

    //底层实现的数组
    private transient Object[] elementData;
    //容器元素数量
    private int size;

ArrayList的构造函数

//指定初始容量,实例化数组。
 public ArrayList(int initialCapacity) {
        super();
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        this.elementData = new Object[initialCapacity];
    }
//无参构造函数,默认使用空数组
public ArrayList() {
        super();
        this.elementData = EMPTY_ELEMENTDATA;
    }
//使用集合来填充数组
 public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        size = elementData.length;
        // c.toArray might (incorrectly) not return Object[] (see 6260652)
        if (elementData.getClass() != Object[].class)
            elementData = Arrays.copyOf(elementData, size, Object[].class);
    }

ArrayList元素增加

 public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // 先确保数组有空间存放新的数据,空间不够就扩容
        elementData[size++] = e;//这里没有null限制,所以是可以放置null在ArrayList中的
        return true;
    }
private void ensureCapacityInternal(int minCapacity) {
        //如果是空数组,就取默认容量大小和minCapacity的最大值作为数组容量
        if (elementData == EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;

        //扩容增加50%
        int newCapacity = oldCapacity + (oldCapacity >> 1); 

        //取newCapacity和minCapacity最大值。
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

        //如果newCapacity>MAX_ARRAY_SIZE=Integer.MAX_VALUE - 8,那就取Integer.MAX_VALUE
        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);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

删除元素 

//删除指定元素,遍历数组,直到找到相等的元素(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;
    }
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
    }

也可以直接删除指定位置的元素

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; // clear to let GC do its work
        //返回删除的元素
        return oldValue;
    }

获取指定位置的元素

public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }
E elementData(int index) {
        return (E) elementData[index];
    }

获取元素的索引位置,找不到返回-1

public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

 判断某个元素是否存在

 public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }

遍历元素

ArrayList继承了AbstractList →AbstractCollection→Collection→Iterable

所以可以直接使用foreach语法直接遍历ArrayList

public static void main(String[] args) {
		ArrayList<Integer> t=new ArrayList<Integer>();
		t.add(1);
		t.add(2);
		t.add(3);
		
		//正序遍历
		for(int i:t){
			System.out.println(i);
		}
        //或者直接使用迭代器
        Iterator<Integer> it=t.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
	}

猜你喜欢

转载自blog.csdn.net/fxkcsdn/article/details/81806683