此类提供 Collection 接口的骨干实现,以最大限度地减少了实现此接口所需的工作,下面我们看看其实现,看看如何通过迭代器实现集合的一些操作。
//Collection的骨干实现
public abstract class AbstractCollection<E> implements Collection<E> {
protected AbstractCollection() {//每个实现该抽象类的,需要提供一个空的构造函数
}
public abstract Iterator<E> iterator();//返回迭代器
public abstract int size();//容量大小
public boolean isEmpty() {//是否为空,可以通过size来判断,所以此处就可以实现该接口
return size() == 0;
}
public boolean contains(Object o) {//判断元素o是否在集合中
Iterator<E> it = iterator();//获得当前迭代器
if (o==null) {//o为null
while (it.hasNext())//通过迭代器迭代判断是否有null的元素
if (it.next()==null)
return true;
} else {//元素不为null
while (it.hasNext())
if (o.equals(it.next()))//判断内容
return true;
}
return false;
}
public Object[] toArray() {//返回集合内元素的数组形式
Object[] r = new Object[size()];//按size申请数组空间
Iterator<E> it = iterator();;//获得迭代器
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) //如果结束了直接返回
return Arrays.copyOf(r, i);//执行数组copy
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;//如果迭代器还有元素,这种情况发生于并发修改集合的过程中
}
//返回具体的数组元素,这里的a只是一个参考值
public <T> T[] toArray(T[] a) {
int size = size();//获得集合大小
//判断集合大小和a的大小,如果a的大小足够大,则用a来存储元素,否则新生成一个数组,注意是用反射生成的,所以其元素类型能保证
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) {
r[i] = null; //赋值为null
} else if (a.length < i) {
return Arrays.copyOf(r, i);//拷贝i个元素,因为a的空间不够,这时通过Arrays.copyOf会创建新的空间
} else {
System.arraycopy(r, 0, a, 0, i);//从r中第0个位置开始拷贝i个元素到a中第0开始的位置
if (a.length > i) {
a[i] = null;
}
}
return a;
}
r[i] = (T)it.next();//迭代器赋值元素
}
return it.hasNext() ? finishToArray(r, it) : r;//如果迭代器还有元素,这种情况发生于并发修改集合的过程中
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;//这里没太理解为什么-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;//扩容原集合长度的2倍+1
if (newCap - MAX_ARRAY_SIZE > 0)//大于最大的元素
newCap = hugeCapacity(cap + 1);//调整到合适的数据,数组的大小不能超过Integer.MAX_VALUE
r = Arrays.copyOf(r, newCap);//执行数据拷贝
}
r[i++] = (T)it.next();//扩容完毕,复制数据
}
return (i == r.length) ? r : Arrays.copyOf(r, i);//返回数组
}
//调整数组大小,最大不能超过Integer.MAX_VALUE
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;
}
//添加元素,目前不支持
public boolean add(E e) {
throw new UnsupportedOperationException();
}
//删除元素,这里是通过迭代器的删除操作来删除元素
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;
}
//判断c中的所有元素是否在集合中
public boolean containsAll(Collection<?> c) {
for (Object e : c)//c继承了Iterable接口,可以用foreach方法
if (!contains(e))
return false;
return true;
}
//添加所有的元素到集合中,其实这个操作也是没实现的
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())) {//不包含在集合c中
it.remove();
modified = true;
}
}
return modified;
}
//执行clear操作
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(' ');
}
}
}