手动实现ArrayList

ArrayList

List 接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null 在内的所有元素。
构造方法:
ArrayList() :构造一个初始容量为 10 的空列表。
ArrayList(Collection<? extends E> c) : 构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。
ArrayList(int initialCapacity) : 构造一个具有指定初始容量的空列表。
方法摘要(部分)
boolean add(E e) 将指定的元素添加到此列表的尾部。
void add(int index, E element) 将指定的元素插入此列表中的指定位置。
boolean addAll(Collection<? extends E> c) 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾部。
boolean addAll(int index, Collection<? extends E> c) 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
void clear() 移除此列表中的所有元素。
boolean contains(Object o) 如果此列表中包含指定的元素,则返回 true。
E get(int index) 返回此列表中指定位置上的元素。
int indexOf(Object o) 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。
boolean isEmpty() 如果此列表中没有元素,则返回 true
int lastIndexOf(Object o) 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。
E remove(int index) 移除此列表中指定位置上的元素。
boolean remove(Object o) 移除此列表中首次出现的指定元素(如果存在)。
E set(int index, E element) 用指定的元素替代此列表中指定位置上的元素。
int size() 返回此列表中的元素数。
Object[] toArray() 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
T[] toArray(T[] a) 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。

手动实现:

import java.util.Arrays;
import java.util.Collection;

public class ArrayList<E> {
	private static final int DEFAULT_CAPACITY = 10;// 初始容量
	transient Object[] elementData;// 存储元素的数组
	private int size;// 数组大小
	private static final Object[] EMPTY_ELEMENTDATA = {};// 空数组

	public ArrayList() {// 无参构造方法
		elementData = new Object[DEFAULT_CAPACITY];// 默认创建一个大小为10的数组
	}

	public ArrayList(int size) {// int型 有参构造方法
		if (size < 0)
			throw new IllegalArgumentException("默认的大小" + size);
		else if (size == 0)// 大小为0,数组为空
			elementData = EMPTY_ELEMENTDATA;
		else
			elementData = new Object[size];// 创建大小为size的数组
	}

	public ArrayList(Collection<? extends E> c) {
		elementData = c.toArray();// 返回包含此 collection 中所有元素的数组
		if ((size = elementData.length) != 0) {
			if (elementData.getClass() != Object[].class)// 返回此 Object 的运行时类
				// 复制指定的数组,截取或用 null 填充(如有必要),以使副本具有指定的长度。
				elementData = Arrays.copyOf(elementData, size, Object[].class);
		} else {
			elementData = EMPTY_ELEMENTDATA;
		}
	}

	private void IsCapacityEnough(int nowsize) {// 判断是否需要扩容
		if (nowsize > DEFAULT_CAPACITY)
			explicitCapacity(nowsize);// 判断是否大于默认大小
	}

	private void explicitCapacity(int nowsize) {
		if (nowsize > elementData.length)
			grow(nowsize);// 如果添加元素后大小超出现有大小,则进行扩容
	}

	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;// 定义一个数组最大的容量的常量为最大值

	private void grow(int nowsize) {// 数组扩容
		int oldCapacity = elementData.length;// 数组长度
		int newCapacity = oldCapacity + (oldCapacity >> 1);// 扩容增加原大小的0.5倍
		if (newCapacity - nowsize < 0)
			newCapacity = nowsize;// 增容后空间仍不够,将增加元素后的大小作为扩容后大小
		if (newCapacity - MAX_ARRAY_SIZE > 0)// 若扩容后大小超过数组最大的容量
			// 判断要需要的扩容空间是否大于数组最大长度,如果大于则容量为 MAX_VALUE ,否则为 MAX_ARRAY_SIZE
			newCapacity = nowsize > MAX_ARRAY_SIZE ? Integer.MAX_VALUE : MAX_ARRAY_SIZE;
		elementData = Arrays.copyOf(elementData, newCapacity);// 扩容后的数组
	}

	public boolean add(E e) {
		IsCapacityEnough(size + 1); // 判断是否需要扩容
		elementData[size++] = e;
		return true;
	}

	private void checkRangeForAdd(int index) {
		if (index < 0 || index > size) {
			throw new IndexOutOfBoundsException("指定的index超过界限");
		}
	}

	public void add(int index, E e) {
		checkRangeForAdd(index);// 判断是否越界
		IsCapacityEnough(size + 1);
		// 将index的元素及以后的元素向后移一位
		System.arraycopy(elementData, index, elementData, index + 1, size - index);
		// 将index下标的值设为e
		elementData[index] = e;
		size++;
	}

	public boolean addAll(Collection<? extends E> c) {// 将该 collection 中的所有元素添加到此列表的尾部
		Object[] a = c.toArray();
		int numNew = a.length;// 集合长度
		IsCapacityEnough(size + numNew); // 判断是否需要扩容
		System.arraycopy(a, 0, elementData, size, numNew);
		size += numNew;
		return numNew != 0;
	}

	public boolean addAll(int index, Collection<? extends E> c) {
		checkRangeForAdd(index);// 下标是否越界

		Object[] a = c.toArray();
		int numNew = a.length;
		IsCapacityEnough(size + numNew); // 是否扩容

		int numMoved = size - index;
		if (numMoved > 0)// 从指定的位置开始,将指定 collection 中的所有元素插入到此列表中。
			System.arraycopy(elementData, index, elementData, index + numNew, numMoved);

		System.arraycopy(a, 0, elementData, index, numNew);
		size += numNew;
		return numNew != 0;
	}

	public void clear() {// 移除此列表中的所有元素
		for (int i = 0; i < size; i++)// 将数组的值设置为空
			elementData[i] = null;
		size = 0;// 设置数组大小为0
	}

	public int indexOf(Object o) {// 返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1
		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 int lastIndexOf(Object o) {// 返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1
		if (o == null) {
			for (int i = size - 1; i >= 0; i--)
				if (elementData[i] == null)
					return i;
		} else {
			for (int i = size - 1; i >= 0; i--)
				if (o.equals(elementData[i]))
					return i;
		}
		return -1;
	}

	public boolean contains(Object o) {// 如果此列表中包含指定的元素,则返回 true
		return indexOf(o) >= 0;// 查找首次出现的指定元素的索引
	}

	public E get(int index) {// 返回此列表中指定位置上的元素
		checkRangeForAdd(index);// 是否越界
		return (E) elementData[index];
	}

	public boolean isEmpty() {// 判断集合是否为空
		return size == 0;// 通过数组大小
	}

	public E remove(int index) {// 移除此列表中指定位置上的元素
		checkRangeForAdd(index);// 是否越界
		E oldValue = (E) elementData[index];
		int numMoved = size - index - 1;// 需前移的元素的个数
		if (numMoved > 0)
			System.arraycopy(elementData, index + 1, elementData, index, numMoved);// 将index后面的元素向前移一位
		elementData[--size] = null;// 缩减size大小,并将原最后一位置空
		return oldValue;
	}

	public boolean remove(Object o) {// 移除此列表中首次出现的指定元素
		if (contains(o)) {// 如果包含指定元素
			remove(indexOf(o));// 移除首次出现的指定元素
			return true;
		} else {
			return false;
		}
	}

	public E set(int index, E element) {// 用指定的元素替代此列表中指定位置上的元素
		checkRangeForAdd(index);// 是否越界
		E oldValue = (E) elementData[index];// 记录指定位置上的元素
		elementData[index] = element;// 赋值
		return oldValue;
	}

	public int size() {// 返回此列表中的元素数
		return size;
	}

	public Object[] toArray() {// 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组。
		return Arrays.copyOf(elementData, size);
	}

	@SuppressWarnings("unchecked")
	public <T> T[] toArray(T[] a) {// 按适当顺序(从第一个到最后一个元素)返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型
		if (a.length < size)
			return (T[]) Arrays.copyOf(elementData, size, a.getClass());
		System.arraycopy(elementData, 0, a, 0, size);
		if (a.length > size)// 如果数组大小大于集合大小,则不可能包含所有
			a[size] = null;
		return a;
	}
}

总结:以上仅供参考,ArrayList的底层是可变数组,有下标,添加顺序和输出顺序一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值