上一篇文章中我们讨论了java集合框架的根接口Collection的源码,这一篇中我们接着分析AbstractCollection类的源码。从类名称AbstractCollection我们就可以看出两点:1,该类应该是个抽象类;2,该类应该与Collection类有着某种联系。实际上AbstractCollection类的确是个抽象类,它提供了Collection接口的默认实现,实现的方式就是利用迭代器逐个操作。因此当我们想自己编写一个集合类时,直接继承AbstractCollection类即可,而不是实现Collection接口中的所有方法,这样可以加速开发(AbstractCollection类已经帮我们实现了部分方法,如果这些实现的方法满足我们的需求就可以直接拿来用即可,不用再自己去开发了。毕竟Collection接口中方法较多,直接实现肯定比继承AbstractCollection类的工作量大)。当需要实现一个不可变集合类的时候,程序员只需要实现size()和iterator方法里的hasNext和Next方法;当需要实现一个可变集合类时,还需要实现增加元素的方法和iterator里的remove方法。
下面是AbstractCollection类的源码
//AbstractCollection是抽象类,提供了接口Collection的默认实现
public abstract class AbstractCollection<E> implements Collection<E> {
//唯一的构造函数,一般用作子类的隐示调用。
protected AbstractCollection() {
}
//返回一个迭代器,关于迭代器的讲解见下面
public abstract Iterator<E> iterator();
//Collection接口中的方法,返回集合元素的大小
public abstract int size();
//判断集合是否为空的默认实现
public boolean isEmpty() {
return size() == 0;
}
//判断集合是否包含对象o的默认实现
public boolean contains(Object o) {
Iterator<E> it = iterator();
if (o==null) {//当o为null时
while (it.hasNext())
if (it.next()==null)
return true;
} else {
while (it.hasNext())
if (o.equals(it.next()))
return true;
}
return false;
}
//将集合转化为数组的默认实现,通过迭代器遍历集合。在遍历集合的时候,集合的结构可能被改变了(如果集合容许的话)
//在并发操作时,集合元素的个数可能不等于最初size()返回的大小
public Object[] toArray() {
// Estimate size of array; be prepared to see more or fewer elements
Object[] r = new Object[size()];
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) // fewer elements than expected
return Arrays.copyOf(r, i);
r[i] = it.next();
}
return it.hasNext() ? finishToArray(r, it) : r;
}
//返回具体类型的数组
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
int size = size();
//如果传入数组的长度大于等于集合的大小则将集合元素填充到数组a中,否则通过反射生成一个大小是size的数组,使用这个数组来容纳集合的元素
T[] r = a.length >= size ? a :
(T[])java.lang.reflect.Array
.newInstance(a.getClass().getComponentType(), size); // 为什么使用反射,不直接new一个呢? 不容许使用泛型数组!!!
Iterator<E> it = iterator();
for (int i = 0; i < r.length; i++) {
if (! it.hasNext()) { // fewer elements than expected
if (a == r) {
r[i] = null; // null-terminate
} else if (a.length < i) { // 此时集合中的元素减少了,判断原数组a能否容下集合元素。
return Arrays.copyOf(r, i);
} else {
System.arraycopy(r, 0, a, 0, i); //原数组a可以容纳下集合元素了,直接使用原数组a。
if (a.length > i) {
a[i] = null;
}
}
return a;
}
r[i] = (T)it.next();
}
// more elements than expected
return it.hasNext() ? finishToArray(r, it) : r;
}
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//私有函数,调用toArray()函数时,当集合中元素增加时调用
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;//扩容为原来的1.5倍,+1是为了防止cap = 0
// overflow-conscious code
if (newCap - MAX_ARRAY_SIZE > 0)
newCap = hugeCapacity(cap + 1);
r = Arrays.copyOf(r, newCap);
}
r[i++] = (T)it.next();
}
// trim if overallocated
return (i == r.length) ? r : Arrays.copyOf(r, i);
}
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();
}
//删除对象o
public boolean remove(Object o) {
Iterator<E> it = iterator();
if (o==null) {//当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)
if (!contains(e))
return false;
return true;
}
//添加集合c中的所有元素
public boolean addAll(Collection<? extends E> c) {
boolean modified = false;
for (E e : c)
if (add(e))
modified = true;
return modified;
}
//删除包含集合c中元素的所有元素
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);//确保c不为null
boolean modified = false;
Iterator<?> it = iterator();
while (it.hasNext()) {
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
//只保留是集合c中的元素
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);//确保c不为null
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
//清空集合
public void clear() {
Iterator<E> it = iterator();
while (it.hasNext()) {
it.next();
it.remove();
}
}
}
其实AbstractCollection实现的方法都比较简单,对于contains,remove方法都是简单的调用迭代器来实现的,当然迭代器的具体实现需要子类去完成。对于bulk opreation 操作就选循环的调用单词操作:比如addAll就是循环的调用add方法。
下面是迭代器的讲解:
接口Iterable源码:
public interface Iterable<T> {
Iterator<T> iterator();
}
只有一个函数iterator(),返回Iterator接口对象,Iterator源码如下:
public interface Iterator<E> {
boolean hasNext();
E next();
default void remove() {
throw new UnsupportedOperationException("remove");
}
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
hasNext():当集合中还有元素是返回true,也就是说还没有遍历完集合。
next():返回下一个元素。
remove():需要子类自己实现(功能是:删除最后一次返回的元素,该方法必须在next之后调用,且每个next方法后只能调用一次remove()函数)。