java.util.Collection体系源码解读<三>AbstractCollection抽象类源码解读

作为Collection接口的骨干实现,AbstractCollection抽象类的源码如下:

package java.util;

/** Collection 接口的骨干实现,以最大限度地减少了实现此接口所需的工作, 此抽象类实现了Collection的一部分方法,而不是全部方法 */
public abstract class AbstractCollection<E> implements Collection<E> {

	/** 无参构造方法 */
	protected AbstractCollection() {
	}

	/** 返回在此 collection 中的元素上进行迭代的迭代器 */
	public abstract Iterator<E> iterator();

	/** 返回此 collection 中的元素数 */
	public abstract int size();

	/** 调用size()==0?true:false,判断集合中是否有元素 */
	public boolean isEmpty() {
		return size() == 0;
	}

	/**
	 * 此 collection 是否包含指定的元素 ,每个元素进行判断,注意判断相等的条件:o==null ? e==null :
	 * o.equals(e)
	 */
	public boolean contains(Object o) {
		Iterator<E> it = iterator();
		// 先判断是否为空元素
		if (o == null) {
			while (it.hasNext())
				if (it.next() == null)
					return true;
		} else {
			while (it.hasNext())
				if (o.equals(it.next()))
					return true;
		}
		return false;
	}

	/** 集合转数组 */
	public Object[] toArray() {
		// 初步设置数组大小
		Object[] r = new Object[size()];
		Iterator<E> it = iterator();
		for (int i = 0; i < r.length; i++) {
			if (!it.hasNext()) // 比预期的元素少就提前返回,浅拷贝
				return Arrays.copyOf(r, i);
			r[i] = it.next();
		}
		return it.hasNext() ? finishToArray(r, it) : r;
	}

	/**
	 * 返回包含此 collection 中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同。如果指定的数组能容纳该
	 * collection,则返回包含此 collection 元素的数组。否则,将分配一个具有指定数组的运行时类型和此 collection
	 * 大小的新数组。
	 */
	public <T> T[] toArray(T[] a) {
		// 初步设定数组的大小
		int size = size();
		T[] r = a.length >= size ? a : (T[]) java.lang.reflect.Array
				.newInstance(a.getClass().getComponentType(), size);
		Iterator<E> it = iterator();

		for (int i = 0; i < r.length; i++) {
			if (!it.hasNext()) {// 可见这里是将指定数组的所有元素添加到转化后的数组的末尾的
				if (a != r)
					return Arrays.copyOf(r, i);
				r[i] = null;
				return r;
			}
			r[i] = (T) it.next();
		}
		return it.hasNext() ? finishToArray(r, it) : r;
	}

	/** 集合能转化为数组时,数组的最大长度 ,如果数组大小超过这个限制会抛出 OutOfMemoryError */
	private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

	/** 动态的扩展数组的长度,实现数组的元素的拷贝 */
	private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
		int i = r.length;
		while (it.hasNext()) {
			int cap = r.length;
			if (i == cap) {
				int newCap = cap + (cap >> 1) + 1;
				// 不能超过最大值得限制
				if (newCap - MAX_ARRAY_SIZE > 0)
					newCap = hugeCapacity(cap + 1);
				r = Arrays.copyOf(r, newCap);
			}
			r[i++] = (T) it.next();
		}
		return (i == r.length) ? r : Arrays.copyOf(r, i);
	}

	/** 获取数组的最大长度,注意长度小于0时抛出OutOfMemoryError */
	private static int hugeCapacity(int minCapacity) {
		if (minCapacity < 0) // overflow
			throw new OutOfMemoryError("Required array size too large");
		return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE
				: MAX_ARRAY_SIZE;
	}

	/** 添加元素,给方法的实现总是要抛出一个添加元素类型不支持的异常 UnsupportedOperationException */
	public boolean add(E e) {
		throw new UnsupportedOperationException();
	}

	/**
	 * 删除元素,注意判断元素相等使用的equals()方法,对于有多个相同元素的集合,只会删除按从前到后的第一个相同的元素,因为删除之后便return了
	 */
	public boolean remove(Object o) {
		Iterator<E> it = iterator();
		if (o == null) {
			while (it.hasNext()) {
				if (it.next() == null) {
					it.remove();
					return true;
				}
			}
		} else {
			while (it.hasNext()) {
				if (o.equals(it.next())) {
					it.remove();
					return true;
				}
			}
		}
		return false;
	}

	/** 是否包含某个集合中的所有元素,注意在遍历过程中调用 contains,如果在遍历过程中本集合中有元素的添加或者删除,那么该结果可能不准确 */
	public boolean containsAll(Collection<?> c) {
		for (Object e : c)
			if (!contains(e))
				return false;
		return true;
	}

	/**
	 * 此实现在指定的 collection 上进行迭代,并依次将迭代器返回的每个对象添加到此 collection
	 * 中(并集),如果全部添加成功,返回true,否则返回false或者添加的过程中抛出异常,所以个人觉得最好在外层做以逻辑或者进行异常的处理
	 */
	public boolean addAll(Collection<? extends E> c) {
		boolean modified = false;
		for (E e : c)
			if (add(e))
				modified = true;
		return modified;
	}

	/** 这个实现会在迭代集合上的所有元素,如果指定的集合中包含迭代的元素,则删除之(差集) */
	public boolean removeAll(Collection<?> c) {
		boolean modified = false;
		Iterator<?> it = iterator();
		while (it.hasNext()) {
			if (c.contains(it.next())) {
				it.remove();
				modified = true;
			}
		}
		return modified;
	}

	/** 迭代集合上中的每一个元素,如果元素不在指定的集合内包含,则删除之(求交集) */
	public boolean retainAll(Collection<?> c) {
		boolean modified = false;
		Iterator<E> it = iterator();
		while (it.hasNext()) {
			if (!c.contains(it.next())) {
				it.remove();
				modified = true;
			}
		}
		return modified;
	}

	/**
	 * 此实现在此 collection 上进行迭代,并使用 Iterator.remove
	 * 操作移除每个元素。为了提高效率,多数实现可能会选择重写此方法。注意该方法并未返回成功与否,也就是说除非抛出异常,否则清理完成
	 */
	public void clear() {
		Iterator<E> it = iterator();
		while (it.hasNext()) {
			it.next();
			it.remove();
		}
	}

	/** 集合字符串转换方法,用方括号 ("[]") 括起每个元素,相邻元素由字符 ", "(逗号加空格)分隔 */
	public String toString() {
		Iterator<E> it = iterator();
		if (!it.hasNext())
			return "[]";

		StringBuilder sb = new StringBuilder();
		sb.append('[');
		for (;;) {
			E e = it.next();
			sb.append(e == this ? "(this Collection)" : e);
			if (!it.hasNext())
				return sb.append(']').toString();
			sb.append(',').append(' ');
		}
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值