前言
public abstract class AbstractCollection<E> implements Collection<E> {
...
}
AbstractCollection抽象类继承自Collection接口,它提供了对Collection接口的基本实现,从而使得实现Collection接口的成本最小化。
如果要实现一个不可被修改的集合,开发者仅需继承此抽象类并提供iterator和size方法的实现即可(通过iterator方法返回的iterator必须实现hasNext和next方法)。
如果要实现一个可以修改的集合,开发者还额外需要覆写add方法(否则会抛出UnsupportedOperationException异常)。通过iterator方法返回的iterator还额外必须实现remove方法。
像Collection接口中建议的那样,开发者一般需要为此抽象类的继承者提供一个无参构造方法和一个参数为Collection的构造方法。
此抽象类中的每个非抽象方法都有着详细的继承描述。如果此抽象类的继承类对性能有着高效的要求,则这些非抽象方法都有可能被重写。
方法解析
1.AbstractCollection()
唯一的构造方法,用来供子类构造方法调用,通常是隐式调用。
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractCollection() {
}
//查询操作
2.iterator()
返回一个包含集合元素的迭代器(iterator)。
/**
* Returns an iterator over the elements contained in this collection.
*
* @return an iterator over the elements contained in this collection
*/
public abstract Iterator<E> iterator();
3.size()
空方法(虽然Collection已定义,但在这里重复定义主要是为了方便,不用在往父接口中去寻找)。
public abstract int size();
4.isEmpty()
返回size()==0的比较结果(或者说返回集合是否为空)。
/**
* {@inheritDoc}
*
* <p>This implementation returns <tt>size() == 0</tt>.
*/
public boolean isEmpty() {
return size() == 0;
}
5.contains(Object o)
遍历集合中的元素,依次检查每个元素是否和指定的元素相等(并返回检查结果)。
/**
* {@inheritDoc}
*
* <p>This implementation iterates over the elements in the collection,
* checking each element in turn for equality with the specified element.
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
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;
}
6.toArray()
此方法返回一个包含iterator方法返回的所有元素的数组,以相同的顺序连续存储在数组中,从索引值为0的数组项开始存储。返回的数组的长度和iterator方法返回的iterator中的元素个数是相等的,即使在遍历时集合的长度改变了(集合允许遍历时可以被修改的情况是有可能发生的)。方法size仅仅是一个优化提示。即使iterator返回的元素的个数和size返回的不相等,此方法依然可以返回正确的结果。
/**
* {@inheritDoc}
*
* <p>This implementation returns an array containing all the elements
* returned by this collection's iterator, in the same order, stored in
* consecutive elements of the array, starting with index {@code 0}.
* The length of the returned array is equal to the number of elements
* returned by the iterator, even if the size of this collection changes
* during iteration, as might happen if the collection permits
* concurrent modification during iteration. The {@code size} method is
* called only as an optimization hint; the correct result is returned
* even if the iterator returns a different number of elements.
*
* <p>This method is equivalent to:
*
* <pre> {@code
* List<E> list = new ArrayList<E>(size());
* for (E e : this)
* list.add(e);
* return list.toArray();
* }</pre>
*/
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;
}
7.toArray(T[] a)
返回一个包含集合迭代器中所有元素的数组,此数组元素的顺序与迭代器中元素的顺序是相同的,并且元素是连续存储在此数组中的,索引值从0开始。
如果集合迭代器返回的元素的数量太多以至于指定的数组不能完全容纳,那么,将返回一个新分配的大小和集合迭代器返回的元素个数相同的数组(存储集合的元素),并且此新数组中元素的顺序和集合迭代器中元素的顺序是相同的,即使在遍历过程中集合的大小改变了(如果此集合允许并发修改,这种情况是有可能发生的)。size方法返回的集合大小并不一定正确,即使集合迭代器返回的元素的数量和size返回的数据不同,但此方法依然可以返回正确的结果。
/**
* {@inheritDoc}
*
* <p>This implementation returns an array containing all the elements
* returned by this collection's iterator in the same order, stored in
* consecutive elements of the array, starting with index {@code 0}.
* If the number of elements returned by the iterator is too large to
* fit into the specified array, then the elements are returned in a
* newly allocated array with length equal to the number of elements
* returned by the iterator, even if the size of this collection
* changes during iteration, as might happen if the collection permits
* concurrent modification during iteration. The {@code size} method is
* called only as an optimization hint; the correct result is returned
* even if the iterator returns a different number of elements.
*
* <p>This method is equivalent to:
*
* <pre> {@code
* List<E> list = new ArrayList<E>(size());
* for (E e : this)
* list.add(e);
* return list.toArray(a);
* }</pre>
*
* @throws ArrayStoreException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
// Estimate size of array; be prepared to see more or fewer elements
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()) { // fewer elements than expected
if (a == r) {
r[i] = null; // null-terminate
} else if (a.length < i) {
return Arrays.copyOf(r, i);
} else {
System.arraycopy(r, 0, a, 0, i);
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;
}
8.finishToArray(T[] r,Iterator<?> it)
当集合迭代器返回的元素的数量比预想的多的时候,对在toArray方法中被使用的数组重新分配大小,并将集合迭代器中的(多出的)元素继续填充到数组中。
/**
* Reallocates the array being used within toArray when the iterator
* returned more elements than expected, and finishes filling it from
* the iterator.
*
* @param r the array, replete with previously stored elements
* @param it the in-progress iterator over this collection
* @return array containing the elements in the given array, plus any
* further elements returned by the iterator, trimmed to size
*/
@SuppressWarnings("unchecked")
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;
// 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);
}
9.hugeCapacity(int minCapacity)
返回集合所能容纳元素个数的最大值。
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;
}
10.containsAll(Collection<?> c)
此方法遍历指定的集合,依次检查每个元素,判断当前集合是否包含相同的元素。如果当前集合包含指定集合的所有元素,返回true,否则,返回false。
/**
* {@inheritDoc}
*
* <p>This implementation iterates over the specified collection,
* checking each element returned by the iterator in turn to see
* if it's contained in this collection. If all elements are so
* contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
*
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @see #contains(Object)
*/
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
11.retainAll(Collection<?> c)
此方法遍历当前集合,依次判断集合迭代器返回的元素是否也包含在指定集合中,如果元素没有包含在指定集合中,则调用当前集合迭代器的remove方法移除此元素(此方法可以理解为取当前集合和指定集合的交集)。
/**
* {@inheritDoc}
*
* <p>This implementation iterates over this collection, checking each
* element returned by the iterator in turn to see if it's contained
* in the specified collection. If it's not so contained, it's removed
* from this collection with the iterator's <tt>remove</tt> method.
*
* <p>Note that this implementation will throw an
* <tt>UnsupportedOperationException</tt> if the iterator returned by the
* <tt>iterator</tt> method does not implement the <tt>remove</tt> method
* and this collection contains one or more elements not present in the
* specified collection.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*
* @see #remove(Object)
* @see #contains(Object)
*/
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}