JAVA集合框架5---ArrayList源码解析

ArrayList是一个动态数组容器,实现了List接口的所有方法,并且可以容纳null,和C++中的vector一样。底层用一个数组来组织数据,所有的方法都是围绕着这个数组进行的。除此之外,ArrayList还提供了两个公有API来对数组大小的操作,分别是trimToSize与ensureCapacity。ArrayList是我们平常使用比较多的一个集合类,掌握它的源码有助于我们更好的使用它。

ArrayList源码如下:

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
    //AbstractList 与 List 的源码与关系在之前的文章中已经分析过了。
    //RandomAccess是随机访问接口,可以在O(1)时间内根据所以返回元素。
    //Cloneable表示可以被克隆(这个拷贝是浅拷贝)。序列化接口Serializable。
    private static final long serialVersionUID = 8683452581122892189L;
    //默认数组的容量大小
    private static final int DEFAULT_CAPACITY = 10;
    //空数组
    private static final Object[] EMPTY_ELEMENTDATA = {};
    //通过无参构造器,也即 new ArrayList<>(),生成对象时的默认空数组
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
    // 以下两个成员变量 elementData与size是ArrayList最主要的两个变量,所有的方法都是围绕着它们两
    //储存元素的数组
    transient Object[] elementData;
    //集合元素的大小
    private int size;
    
    //构造函数
    //给elementData数组一个初始大小
    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);
        }
    }
    //无参构造函数
    public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    //通过其它集合来初始化elementData
    public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray(); // toArray 集合与数组之间的转化桥梁
        if ((size = elementData.length) != 0) {
            // defend against c.toArray (incorrectly) not returning Object[]
            // (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
            if (elementData.getClass() != Object[].class) // 意思是如果 toArray 返回类型不是 Object[] ,那么在重新复制一份
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }
}

 分析完构造函数之后,下面分析两个对数组elementData大小直接操作的两个函数

//缩减elementData数组的大小,使其刚好等于集合大小
public void trimToSize() {
	modCount++; // modCount 继承自AbstractList
	if (size < elementData.length) {
		elementData = (size == 0)
		  ? EMPTY_ELEMENTDATA
		  : Arrays.copyOf(elementData, size);
	}
}
//确保elementData的大小至少为minCapacity.这个函数是给外界调用的,在ArrayList里面并没有使用到这个函数
public void ensureCapacity(int minCapacity) {
	if (minCapacity > elementData.length
		&& !(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
			 && minCapacity <= DEFAULT_CAPACITY)) {  // 当ArrayList对象是通过无参构造函数创建且minCapacity小于等于DEFAULT_CAPACITY(10)时,什么也不做。
		modCount++;
		grow(minCapacity);
	}
}

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

private Object[] grow(int minCapacity) {
	return elementData = Arrays.copyOf(elementData,newCapacity(minCapacity));
}

private Object[] grow() {
	return grow(size + 1);
}
private int newCapacity(int minCapacity) {
	// overflow-conscious code
	int oldCapacity = elementData.length;
	int newCapacity = oldCapacity + (oldCapacity >> 1);  //每次扩容1.5倍
	if (newCapacity - minCapacity <= 0) {
		if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
			return Math.max(DEFAULT_CAPACITY, minCapacity);
		if (minCapacity < 0) // overflow
			throw new OutOfMemoryError();
		return minCapacity;
	}
	return (newCapacity - MAX_ARRAY_SIZE <= 0)
		? newCapacity
		: hugeCapacity(minCapacity);
}
private static int hugeCapacity(int minCapacity) {
	if (minCapacity < 0) // overflow
		throw new OutOfMemoryError();
	return (minCapacity > MAX_ARRAY_SIZE)
		? Integer.MAX_VALUE
		: MAX_ARRAY_SIZE;
}

查询操作源码:

// 返回长度
public int size() {
	return size;
}
//判断是否为空
public boolean isEmpty() {
	return size == 0;
}
//判断是否包含对象o
public boolean contains(Object o) {
	return indexOf(o) >= 0;
}
//返回对象o的索引,不存在就返回-1
public int indexOf(Object o) {
	return indexOfRange(o, 0, size);
}
int indexOfRange(Object o, int start, int end) {
	Object[] es = elementData;
	if (o == null) {
		for (int i = start; i < end; i++) {
			if (es[i] == null) {
				return i;
			}
		}
	} else {
		for (int i = start; i < end; i++) {
			if (o.equals(es[i])) {
				return i;
			}
		}
	}
	return -1;
}
public int lastIndexOf(Object o) {
	return lastIndexOfRange(o, 0, size);
}
int lastIndexOfRange(Object o, int start, int end) {
	Object[] es = elementData;
	if (o == null) {
		for (int i = end - 1; i >= start; i--) {
			if (es[i] == null) {
				return i;
			}
		}
	} else {
		for (int i = end - 1; i >= start; i--) {
			if (o.equals(es[i])) {
				return i;
			}
		}
	}
	return -1;
}
E elementData(int index) {
	return (E) elementData[index];
}
public E get(int index) {
	Objects.checkIndex(index, size); //检测输入是否合法
	return elementData(index);
}

修改操作:

//更改指定索引处的元素
public E set(int index, E element) {
	Objects.checkIndex(index, size);
	E oldValue = elementData(index);
	elementData[index] = element;
	return oldValue;
}
private void add(E e, Object[] elementData, int s) {
	if (s == elementData.length)
		elementData = grow();  // 如果索引s等于elementData数组的容量,扩容
	elementData[s] = e;  // 插入
	size = s + 1;  // 更新size
}
// 添加元素到末尾
public boolean add(E e) {
	modCount++;
	add(e, elementData, size);
	return true;
}
// 在指定索引处插入元素
public void add(int index, E element) {
	rangeCheckForAdd(index);
	modCount++;
	final int s;
	Object[] elementData;
	if ((s = size) == (elementData = this.elementData).length)
		elementData = grow();
	System.arraycopy(elementData, index,elementData, index + 1,s - index);  // index处之后的元素向后移一位,为新插入的元素腾空间
	elementData[index] = element;
	size = s + 1;
}
//根据索引删除元素,返回删除的元素
public E remove(int index) {
	Objects.checkIndex(index, size);
	final Object[] es = elementData;

	@SuppressWarnings("unchecked") E oldValue = (E) es[index];
	fastRemove(es, index);

	return oldValue;
}
//根据对象删除元素
public boolean remove(Object o) {
	final Object[] es = elementData;
	final int size = this.size;
	int i = 0;
	found: {
		if (o == null) {
			for (; i < size; i++)
				if (es[i] == null)
					break found;  // 带标签的break语法
		} else {
			for (; i < size; i++)
				if (o.equals(es[i]))
					break found;
		}
		return false;
	}
	fastRemove(es, i);
	return true;
}
private void fastRemove(Object[] es, int i) {
	modCount++;
	final int newSize;
	if ((newSize = size - 1) > i)
		System.arraycopy(es, i + 1, es, i, newSize - i);
	es[size = newSize] = null;
}
public void clear() {
	modCount++;
	final Object[] es = elementData;
	for (int to = size, i = size = 0; i < to; i++)
		es[i] = null;
}

批量修改操作源码:

// 添加集合c中的所有元素到末尾
public boolean addAll(Collection<? extends E> c) {
	Object[] a = c.toArray();
	modCount++;
	int numNew = a.length;
	if (numNew == 0)
		return false;
	Object[] elementData;
	final int s;
	if (numNew > (elementData = this.elementData).length - (s = size))  // 判断数组elementData能否容纳集合c中的所有元素,不能就扩容
		elementData = grow(s + numNew);
	System.arraycopy(a, 0, elementData, s, numNew);
	size = s + numNew;
	return true;
}
//在指定位置添加集合c中的所有元素
public boolean addAll(int index, Collection<? extends E> c) {
	rangeCheckForAdd(index); // 检测index是否合法

	Object[] a = c.toArray();
	modCount++;
	int numNew = a.length;
	if (numNew == 0)
		return false;
	Object[] elementData;
	final int s;
	if (numNew > (elementData = this.elementData).length - (s = size))
		elementData = grow(s + numNew);

	int numMoved = s - index;
	if (numMoved > 0)
		System.arraycopy(elementData, index,elementData, index + numNew,numMoved); //将index之后的元素向后移
	System.arraycopy(a, 0, elementData, index, numNew);
	size = s + numNew;
	return true;
}
// 删除集合c中的所有元素
public boolean removeAll(Collection<?> c) {
	return batchRemove(c, false, 0, size);
}
// 保留那些集合c与elementData都有的元素
public boolean retainAll(Collection<?> c) {
	return batchRemove(c, true, 0, size);
}

boolean batchRemove(Collection<?> c, boolean complement,
					final int from, final int end) {
	Objects.requireNonNull(c); // 确保集合c不为null
	final Object[] es = elementData;
	int r;
	// Optimize for initial run of survivors
    // 优化初始位置
	for (r = from;; r++) {
		if (r == end)
			return false;
		if (c.contains(es[r]) != complement)
			break;
	}
    // 其实就是两层for循环,时间复杂度为O(n^2)。contains是线性搜索,时间复杂度为O(n)
	int w = r++;
	try {
		for (Object e; r < end; r++)
			if (c.contains(e = es[r]) == complement)
				es[w++] = e;
	} catch (Throwable ex) {
		// Preserve behavioral compatibility with AbstractCollection,
		// even if c.contains() throws.
		System.arraycopy(es, r, es, w, end - r);
		w += end - r;
		throw ex;
	} finally {
		modCount += end - w;
		shiftTailOverGap(es, w, end);
	}
	return true;
}
// 将从索引hi开始的元素移到从lo开始,也就是抹掉lo---hi 之间的元素 (左闭右开)
private void shiftTailOverGap(Object[] es, int lo, int hi) {
	System.arraycopy(es, hi, es, lo, size - hi);
	for (int to = size, i = (size -= hi - lo); i < to; i++)
		es[i] = null;
}

重写Object类的源码:(比较简单,直接看就明白了)

public boolean equals(Object o) {
	if (o == this) {
		return true;
	}

	if (!(o instanceof List)) {
		return false;
	}

	final int expectedModCount = modCount;
	// ArrayList can be subclassed and given arbitrary behavior, but we can
	// still deal with the common case where o is ArrayList precisely
	boolean equal = (o.getClass() == ArrayList.class)
		? equalsArrayList((ArrayList<?>) o)
		: equalsRange((List<?>) o, 0, size);

	checkForComodification(expectedModCount);
	return equal;
}
boolean equalsRange(List<?> other, int from, int to) {
	final Object[] es = elementData;
	if (to > es.length) {
		throw new ConcurrentModificationException();
	}
	var oit = other.iterator();
	for (; from < to; from++) {
		if (!oit.hasNext() || !Objects.equals(es[from], oit.next())) {
			return false;
		}
	}
	return !oit.hasNext();
}
private boolean equalsArrayList(ArrayList<?> other) {
	final int otherModCount = other.modCount;
	final int s = size;
	boolean equal;
	if (equal = (s == other.size)) {
		final Object[] otherEs = other.elementData;
		final Object[] es = elementData;
		if (s > es.length || s > otherEs.length) {
			throw new ConcurrentModificationException();
		}
		for (int i = 0; i < s; i++) {
			if (!Objects.equals(es[i], otherEs[i])) {
				equal = false;
				break;
			}
		}
	}
	other.checkForComodification(otherModCount);
	return equal;
}

private void checkForComodification(final int expectedModCount) {
	if (modCount != expectedModCount) {
		throw new ConcurrentModificationException();
	}
}
public int hashCode() {
	int expectedModCount = modCount;
	int hash = hashCodeRange(0, size);
	checkForComodification(expectedModCount);
	return hash;
}
int hashCodeRange(int from, int to) {
	final Object[] es = elementData;
	if (to > es.length) {
		throw new ConcurrentModificationException();
	}
	int hashCode = 1;
	for (int i = from; i < to; i++) {
		Object e = es[i];
		hashCode = 31 * hashCode + (e == null ? 0 : e.hashCode());
	}
	return hashCode;
}

迭代器Iterator与listIterator的实现类与上一篇的实现几乎是一样的。

猜你喜欢

转载自blog.csdn.net/qq_22158743/article/details/87717185
今日推荐