一、简介
Collection是集合层次结构的根接口。集合代表一组对象,每个对象称为集合中的元素。一些集合不允许重复的元素(Set等),一些允许重复的元素(List等)。一些集合无序(Set等),一些集合有序(List等)。JDK并不提供任何的直接实现这个接口,它提供了更具体的实现子接口如Set和List。通常使用这个接口通过集合,操纵它们最大共性是理想的地方。①可能包含重复元素的无序集合应直接实现此接口。②所有通用的Collection实现类(通常间接的实现Collection,通常实现它的子实现接口,如Set,List)应提供标准的两个构造函数:一个空构造函数(没有参数),它创建一个空集合,一个参数的构造函数,参数类型是Collection,它创建一个新的集合,元素和传入的集合一样(涉及深拷贝和浅拷贝,普通类型和字符串是深拷贝,对象引用类型是浅拷贝)。实际上,后者构造函数允许用户复制任何集合,产生一个等价的理想的实现类型的集合。没有办法执行本约定(接口不能包含构造函数,如List、Set),但所有的通用集合实现遵守Java平台库。③此接口中包含的“破坏性”的方法,也就是说,这些接口会修改集合但它们被操作,如果这个集合不支持该操作,抛出UnsupportedOperationException异常。如果是这样的话,如果被调用不会修改集合,这些方法不要求抛出一个UnsupportedOperationException异常。例如,在调用了一个不可改变的集合的{@link #addAll(Collection)}方法,如果添加参数集合是空的,抛出UnsupportedOperationException异常不是必需的。④有些集合实现限制它们可能包含的元素。例如,有些集合实现禁止null元素,不允许添加null元素,有些集合实现限制元素的类型。试图添加一个不合格的元素抛出一个运行时异常,通常NullPointerException或者ClassCastException。试图查询一个不合格的元素是否存在可能会抛出一个异常,或者可能只是返回false。更普遍的是,试图操作一个不合格的元素的完成不会导致一个不合格的元素插入集合可能抛出异常或者它可能成功,选择的实现,这样的例外是标记为“可选"这个接口的规范。⑤它是每个集合来确定自己的同步策略。在实现类缺乏更强的保证,未定义的行为可能导致调用集合的任何方法是被另一个线程突变。这包括直接调用,通过集合可以执行调用的方法,并使用现有的迭代器检查集合。Collection框架接口定义的许多方法和{@link Object#equals(Object)}。例如,规范{@link #contains(Object)} contains(Object o)如果返回true,当且仅当这个集合包含至少一个元素e,(o == null ? e== null : o.equals(e))。这个规范不应该被解释为调用Collection.contains(o),将导致调用集合中的所有元素与非空参数o,o.euqals(e)。实现自由来实现优化,避免equals被调用,例如,通过比较这两个元素的哈希码hashCode,{@link Object#hashCode()}规范保证两个对象不相等当哈希码不相等。更普遍的是,各种集合框架接口的实现可以自由利用的指定行为{@link Object}方法,只要实现者认为适当。⑥一些集合操作执行递归遍历集合可能会失败,集合直接或者间接包含集合本身。这包括{@code clone()},{@code equals()},{@code hashCode()}和{@code toString()}方法。实现可能会选择性地处理自我包含集合本身的场景,然而大多数当前的实现并不这样做。⑦默认的方法实现(继承或其他)不适用任何同步协议。如果{@code Collection}实现一个特定的同步协议,那么它必须覆盖缺省实现应用协议。Collection结构图如下图(来自网上)
二、类关系
Iterable
/**
* 实现了这个接口允许将一个对象做为for-each循环的声明目标
*
* @param <T> 迭代器返回的元素类型
*/
public interface Iterable<T> {
/**
* 返回一个迭代器,元素类型为{@code T}
*
* @return an Iterator 一个迭代器
*/
Iterator<T> iterator();
/**
* 为每个元素执行给定的操作的,直到所有的元素都已经被处理或操作将抛出一个异常。顺序迭代的执行动作(如果指定迭代顺序)
* ,抛出的异常动作传递给调用者
*
* @implSpec
* <p>如果默认实现的行为:
* <pre>{@code
* for (T t : this)
* action.accept(t);
* }</pre>
*
* @param 为每个元素执行的行动
* @throws NullPointerException 如果指定的行为是空
*/
default void forEach(Consumer<? super T> action) {
Objects.requireNonNull(action);
for (T t : this) {
action.accept(t);
}
}
/**
* 创建一个{@link Spliterator}
*
* @implSpec实现规范
* iterable创建一个默认实现早绑定的spliterator
* 一个迟绑定的spliterator在第一次遍历,第一次分割或者第一次对预计大小查询时与元素来源绑定,
* 而不是在spliterator被创建时绑定。
* 一个不是迟绑定的spliterator在创建或者任何方法的第一次调用时绑定。
* 在绑定之前对来源的修改会在spliterator遍历时显示出来
* spliterator继承了fail-fast,快速失败
*
*
* @implNote实现注意事项
* 通常应该覆盖默认的实现,返回一个更加高效的spliterator。
* 返回的spliterator默认实现分割差,对元素不可计数,不报告任何spliterator特征。
* 实现类可以提供一个更好的实现
*
* @return 一个可分割的迭代器
*/
default Spliterator<T> spliterator() {
return Spliterators.spliteratorUnknownSize(iterator(), 0);
}
}
Iterator
/**
* 迭代器遍历一个集合。{@code Iterator}代替{@link Enumeration}在java集合框架。Iterator
* 不同于enumerations在两个方面
* <ul>
* <li> iterators迭代器允许调用者从底层集合删除元素,iterators迭代器定义良好的语义.
* <li> 方法名称得到改进.
* </ul>
*
* @param <T> 迭代器返回的元素类型
*/
public interface Iterator<E> {
/**
* 返回 {@code true} 如果迭代器有更多的元素.
* (换句话说, 返回 {@code true} 如果 {@link #next} 返回一个元素而不是抛出异常.)
*
* @return {@code true} 如果迭代有更多的元素
*/
boolean hasNext();
/**
* 返回迭代的下一个元素.
*
* @return 返回迭代的下一个元素
* @throws NoSuchElementException 如果迭代中没有更多的元素
*/
E next();
/**
* 删除迭代器从底层集合返回的最后一个元素 (可选操作). 这个方法可以被称为每调用一次{@link #next}.
* 迭代器的行为是不确定的,如果底层集合被修改在迭代过程中以任何方式除了通过调用这个方法。
* is unspecified if the underlying collection is modified while the
* iteration is in progress in any way other than by calling this
* method.
*
* @implSpec实现规范
* 默认实现抛出一个
* {@link UnsupportedOperationException} 并且没有执行任何操作.
*
* @throws UnsupportedOperationException 如果 {@code remove}
* 操作在这个迭代器不支持
*
* @throws IllegalStateException 如果 {@code next} 方法从来没有
* 被调用, 或者 {@code remove} 方法总是在最后调用 {@code next}
* 方法后调用,即next已经没有元素,remove会报IllegalStateException
*/
default void remove() {
throw new UnsupportedOperationException("remove");
}
/**
* 为每个剩余元素执行给定的操作,,直到所有的元素都已经被处理或行动将抛出一个异常
* 行动顺序迭代执行,如果顺序是指定的.抛出的异常动作传递给调用者
*
* @implSpec实现规范
* <p>默认的实现行为如下:
* <pre>{@code
* while (hasNext())
* action.accept(next());
* }</pre>
*
* @param action 为每个元素执行的行动
* @throws NullPointerException 如果指定的行为是空
*/
default void forEachRemaining(Consumer<? super E> action) {
Objects.requireNonNull(action);
while (hasNext())
action.accept(next());
}
}
三、方法
/**
* 返回此集合的元素数量. 如果这个集合
* 包含超过 <tt>Integer.MAX_VALUE</tt> 元素, returns
* <tt>Integer.MAX_VALUE</tt>数量.
*
* @return 在这个集合的元素数量
*/
int size();
/**
* 返回 <tt>true</tt> 如果这个集合不包含任何元素.
*
* @return <tt>true</tt> 如果这个集合不包含任何元素
*/
boolean isEmpty();
/**
* 返回 <tt>true</tt> 如果集合包含指定的元素.
* 更正式, 返回 <tt>true</tt> 当且仅当这个集合包含至少一个元素 <tt>e</tt> 正如
* <tt>(o==null?e==null:o.equals(e))</tt>.
*
* @param o 指定元素
* @return <tt>true</tt> 如果集合包含指定的元素
* @throws ClassCastException 如果指定元素的类型与这个集合不相容,可选操作
* @throws NullPointerException 如果指定的元素为null,并且这个集合不允许null元素
*/
boolean contains(Object o);
/**
* 返回一个遍历这个集合元素的迭代器.
* 没有担保有关的元素顺序返回(除非这个集合是有序提供一个保证)
*
* @return 返回一个遍历这个集合元素的迭代器
*/
Iterator<E> iterator();
/**
* 返回一个数组,包含这个集合的所有元素。
* 如果这个集合担保顺序返回元素迭代器,该方法必须在相同的顺序返回元素。
*
* <p>如果集合没有包含引用对象,返回的数组将安全,深copy和浅copy。(换句话说,这个方法必须分配一个新数组,
* 即使这个集合是由一个数组),调用者可以自由修改返回的数组
*
* <p>这种方法给数组和集合充当桥梁.
*
* @return 返回包含集合所有元素的一个数组
*/
Object[] toArray();
/**
* 返回一个数组,包含这个集合的所有元素;
* 返回的数组元素类型是指定的数组的元素类型.如果指定的数组容量大于集合容量,指定的数组会被返回。
* 否则,一个新的数组将被分配,数组的元素类型为指定数组的元素类型,数组的大小为这个集合的大小。
*
* <p>如果数组容量比集合大小更大,集合会填充到指定数组的空闲空间,超过集合大小的那些数组位置元素都置为null
*
* <p>如果这个集合担保顺序返回元素迭代器,该方法必须在相同的顺序返回元素.
*
* <p>就像{@link #toArray()} 方法, 这种方法给数组和集合充当桥梁.
* 此外,这个方法允许精确控制输出数组的运行时类型,在某些情况下,被用来节省分配成本,
*
* <p>假设 <tt>x</tt> 集合只含有字符串元素.
* 下面的代码可以用转储收集到一个新分配的数组字符串
*
* <pre>
* String[] y = x.toArray(new String[0]);</pre>
*
* 请注意 <tt>toArray(new Object[0])</tt> 和
* <tt>toArray()</tt>在功能上是一样的.
*
* @param <T> 数组包含的元素类型
* @param a 如果指定的这个数组容量足够大,集合元素将会存储在这个数组;否则一个新的数组将被分配,元素类型为指定数组的元素类型.
* @return 一个数组,其中包含集合的所有元素
* @throws ArrayStoreException 如果指定数组的元素类型不是集合元素类型的父类
* @throws NullPointerException 如果指定的数组是null
*/
<T> T[] toArray(T[] a);
// 修改操作
/**
* 将指定元素加到集合中,确保这个集合包含指定的元素 (可选操作).
* 返回true,如果集合在被调用这个方法后改变. (返回 <tt>false</tt>
* 如果这个集合不允许包含重复元素,并且集合已经包含指定的元素.)<p>
*
* 集合支持限制某些元素不能被添加到这个集合操作。特别是一些集合拒绝添加null元素。
* 和其他人将限制可能添加的元素的类型。集合类应该清楚的指定添加任何限制元素的注释文档
*
* 如果一个集合拒绝添加一个特定的元素,它已经包含了元素以外的任何理由,必须抛出异常,而不是返回false.
*
* @param e 指定元素加到集合中
* @return <tt>true</tt> 如果集合在被调用这个方法后改变
* @throws UnsupportedOperationException 如果 <tt>add</tt> 操作
* 在这个集合不支持
* @throws ClassCastException 如果指定元素的类型不是集合元素类型的超类
* @throws NullPointerException 如果指定元素是null,并且这个集合不允许添加null元素
* @throws IllegalArgumentException 如果指定元素的某些属性可以防止它被添加到这个集合中
* @throws IllegalStateException 如果元素不能被添加由于插入的限制
*/
boolean add(E e);
/**
* 从这个集合删除指定元素,如果它存在(可选操作)
* 更正式,移除e这个元素,正如(o==null?e==null:o.equals(e))
* 如果这个集合包含一个或者多个这样的元素。返回true,如果集合包含指定的元素,调用这个方法集合改变
*
* @param o 从集合把这个元素删除,如果这个元素存在
* @return <tt>true</tt> 返回true,如果集合包含指定的元素,调用这个方法集合改变
* @throws ClassCastException 如果指定元素的类型与这个集合不相容
* @throws NullPointerException 如果指定元素是null,并且这个集合不允许添加null元素
* @throws UnsupportedOperationException 如果这个集合不支持删除操作
*/
boolean remove(Object o);
// 批量操作
/**
* 返回 <tt>true</tt> 如果集合包含指定集合的所有元素.
*
* @param c 指定集合将被检查,指定集合所有元素是否在这个集合内
* @return 返回<tt>true</tt> 如果集合包含指定集合的所有元素
* @throws ClassCastException 在指定集合中有一个或多个元素的类型和这个集合不相容
* @throws NullPointerException 如果指定集合包含一个或者多个null元素并且当前集合不允许null元素,
* @see #contains(Object)
*/
boolean containsAll(Collection<?> c);
/**
* 添加指定集合中的所有元素加到这个集合(可选操作)
* 这个操作的行为是未定义的,如果指定的集合被修改当这个方法还在进行中
*
* @param c 指定集合,指定集合中的所有元素加到这个集合
* @return 返回<tt>true</tt> 如果调用后集合改变
* @throws UnsupportedOperationException 如果 <tt>addAll</tt> 操作
* 在这个集合不支持
* @throws ClassCastException 如果指定元素的类型与这个集合不相容
* @throws NullPointerException 如果指定的集合含有null元素,但当前集合不支持null元素
* 或者指定的集合是null
* @throws IllegalArgumentException 如果指定中至少有一个元素的某些属性可以防止它被添加到这个集合中
* @throws IllegalStateException 如果元素不能被添加由于插入的限制
* @see #add(Object)
*/
boolean addAll(Collection<? extends E> c);
/**
* 在这个集合删除指定集合的所有元素(可选操作)。这个调用返回后,这个集合不包含指定集合的元素
*
* @param c 集合包含的所有元素从这个集合移除
* @return <tt>true</tt> 如果这个集合在调用这个方法后改变
* @throws UnsupportedOperationException 如果 <tt>removeAll</tt> 方法
* 在这个集合不支持
* @throws ClassCastException 如果指定集合含有一个或多个元素的类型与这个集合不相容
* @throws NullPointerException 如果指定的集合含有null元素,但当前集合不支持null元素
* 或者指定的集合是null
* @see #remove(Object)
* @see #contains(Object)
*/
boolean removeAll(Collection<?> c);
/**
* 删除这个集合所有满足给定Predicate的元素,错误或者运行时异常在迭代或者在这个Predicate期间,异常传递给调用者
*
* @implSpec
* 默认实现使用其迭代器遍历集合所有元素
* 每一个匹配的元素将调用{@link Iterator#remove()}移除。如果集合迭代器不支持remove方法,
* {@code UnsupportedOperationException}异常将被抛出在第一个匹配的元素
*
* @param filter 如果 predicate 返回 {@code true} 这个元素将被移除
* @return {@code true} 如果任何一个元素被移除
* @throws NullPointerException 如果指定的filter是null
* @throws UnsupportedOperationException 如果集合不支持remove.实现可能会抛出这个异常
* 如果一个匹配的元素不能被删除,集合不支持remove方法
*/
default boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
boolean removed = false;
final Iterator<E> each = iterator();
while (each.hasNext()) {
if (filter.test(each.next())) {
each.remove();
removed = true;
}
}
return removed;
}
/**
* 集合只保留指定集合的所有元素(可选操作)。换句话说,从这个集合删除所有不包含在指定的集合的元素
*
* @param c 集合只保留指定集合的所有元素
* @return <tt>true</tt> 如果这个方法调用后,集合改变
* @throws UnsupportedOperationException 如果 <tt>retainAll</tt> 操作
* 在这个集合不被支持
* @throws ClassCastException 如果指定集合含有一个或多个元素的类型与这个集合不相容
* @throws NullPointerException 如果指定的集合含有null元素,但当前集合不支持null元素
* 或者指定的集合是null
* @see #remove(Object)
* @see #contains(Object)
*/
boolean retainAll(Collection<?> c);
/**
* 移除集合的所有元素 (可选操作).
* 这个方法调用后集合不含有元素.
*
* @throws UnsupportedOperationException 如果 <tt>clear</tt> 操作
* 在集合不被支持
*/
void clear();
// 比较和哈希值
/**
* 比较指定的对象与此集合是否相等. <p>
*
* <tt>Collection</tt> 集合没有规定<tt>Object.equals</tt>方法
* 程序员直接实现<tt>Collection</tt>接口(换句话说,创建一个集合,但是这个集合不是
* <tt>Set</tt>或者<tt>List</tt>)
* 如果选择覆盖<tt>Object.equals</tt>方法,应该考虑清楚
* 没有必要这样做,最简单的做法是依靠<tt>Object</tt>实现,但实现者可能希望实现一个”值比较“
* 代替默认的引用比较。
* (<tt>List</tt> 和 <tt>Set</tt> 接口授权这样的值比较.)<p>
*
* 一般 <tt>Object.equals</tt> 方法必须是对称的
* (换句话说, <tt>a.equals(b)</tt> 只有<tt>b.equals(a)</tt>).
*
* @param o 与这个集合对象比较相等
* @return <tt>true</tt> 如果指定的对象和这个集合相等
*
* @see Object#equals(Object)
* @see Set#equals(Object)
* @see List#equals(Object)
*/
boolean equals(Object o);
/**
* 返回此集合的哈希码值. 当这个
* <tt>Collection</tt> 接口没有规定<tt>Object.hashCode</tt>方法
* 程序员应该注意,覆盖 <tt>Object.equals</tt>
* 方法 必须同样实现 <tt>Object.hashCode</tt> 方法 in order
* 特别是, <tt>c1.equals(c2)</tt> 意味着
* <tt>c1.hashCode()==c2.hashCode()</tt>.
*
* @return 这个集合的哈希码值
*
* @see Object#hashCode()
* @see Object#equals(Object)
*/
int hashCode();
@Override
default Spliterator<E> spliterator() {
return Spliterators.spliterator(this, 0);
}
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
四、子类
AbstractCollection
/**
* 这个类提供了一个实现Collection接口骨架,以减少其他类实现Collection这个接口所需的努力
*
* 实现一个不可修改的集合,程序员只需要扩展这个类并提供<tt>iterator</tt> 和
* <tt>size</tt>方法,(迭代器从这个 <tt>iterator</tt>方法返回
* 并且返回的迭代器需要实现<tt>hasNext</tt> 和 <tt>next</tt>方法.)<p>
*
* 实现一个可修改的集合,程序员必须另外覆盖这个类的<tt>add</tt>方法(否则默认实现抛出一个
* <tt>UnsupportedOperationException</tt>异常)
* 并且迭代器从<tt>iterator</tt>方法返回,返回的迭代器还需要额外实现<tt>remove</tt>方法
* 即返回的迭代器需要实现tt>hasNext</tt> 和 <tt>next</tt>方法,还需要实现<tt>remove</tt>方法
*
* 程序员通常提供一个无参数和一个Collection集合的构造函数,按照推荐的<tt>Collection</tt>接口规范
*
* 每个非抽象的方法在这个类的文档注释详细描述它的实现。这些方法可能会被覆盖,如果实现集合更高效的实现
*/
public abstract class AbstractCollection<E> implements Collection<E> {
/**
* 唯一的构造函数(由子类的构造函数隐式的调用)
*/
protected AbstractCollection() {
}
// 查询操作
/**
* 返回一个遍历该集合元素的迭代器.需子类进行实现
*
* @return 返回一个遍历该集合元素的迭代器
*/
public abstract Iterator<E> iterator();
/**
* 返回该集合包含的元素数量,需由子类进行实现
*/
public abstract int size();
/**
* <p>实现返回 <tt>size() == 0</tt>.
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* <p>使用迭代器遍历集合元素,依次和指定的元素进行比较.
*
* @throws ClassCastException 如果指定元素的类型与这个集合不相容,可选操作
* @throws NullPointerException 如果指定的元素为null,并且这个集合不允许null元素
*/
public boolean contains(Object o) {
//获取迭代器
Iterator<E> it = iterator();
//如果指定的元素为null,从集合中判断是否存在null元素
if (o==null) {
while (it.hasNext())
//如果集合中存在null元素,返回true,否则返回false
if (it.next()==null)
return true;
} else {
//如果指定的集合非null,循环遍历集合元素,使用equals判断和指定元素是否相等
while (it.hasNext())
//如果集合中存在元素equals(o),返回true,否则返回false
if (o.equals(it.next()))
return true;
}
return false;
}
/**
*
* <p>这个实现返回一个数组,数组包含集合的所有元素.获取集合元素通过迭代器进行遍历,和集合相同的顺序连续存储在数组,从集合下标0开始
* 返回数组的长度等于迭代器返回元素的数量,即使这个集合的大小变化在迭代期间,期间可能会发生如果集合允许并发修改.
*
* <p>这个方法和以下是等价的:
*
* <pre> {@code
* List<E> list = new ArrayList<E>(size());
* for (E e : this)
* list.add(e);
* return list.toArray();
* }</pre>
*/
public Object[] toArray() {
// 估计数组的大小,运行期间可能看到更多或更少的元素
Object[] r = new Object[size()];
//获取迭代器
Iterator<E> it = iterator();
//使用数组的长度进行遍历
for (int i = 0; i < r.length; i++) {
//如果没有下一个元素
if (! it.hasNext()) // 比预期更少的元素,迭代期间有集合元素被删除
//copy一份长度为i的数组
return Arrays.copyOf(r, i);
//将迭代器的下一个元素赋值给数组下标为i的位置
r[i] = it.next();
}
//如果在迭代将元素赋值给数组的期间,有元素添加到集合中,调用finishToArray将新增的元素加到集合中,finishToArray方法下面进行介绍,否则直接返回数组
return it.hasNext() ? finishToArray(r, it) : r;
}
/**
* {@inheritDoc}
*
* <p>这个实现返回一个数组,数组包含集合的所有元素.获取集合元素通过迭代器进行遍历,和集合相同的顺序连续存储在数组,从集合下标0开始.
* 如果传入的数组大小大于迭代器返回的元素数量,将集合元素填充到数组中,返回传入的数组,
* 否则新分配一个数组长度等于迭代器返回的元素数量,即使这个集合的大小变化在迭代期间,集合允许并发修改.
*
* <p>这个方法和以下是等价的:
*
* <pre> {@code
* List<E> list = new ArrayList<E>(size());
* for (E e : this)
* list.add(e);
* return list.toArray(a);
* }</pre>
*
* @throws ArrayStoreException 如果指定数组的元素类型不是集合元素类型的父类
* @throws NullPointerException 如果指定的数组是null
*/
@SuppressWarnings("unchecked")
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()) { // 比预期更少的元素,迭代期间有集合元素被删除
//如果数组r是传入进来的数组a
if (a == r) {
//迭代期间有集合元素被删除,将i位置元素置为null
r[i] = null; // null-terminate
} else if (a.length < i) {//如果数组r不是传入进来的数组a,并且传入进来的数组a长度小于i
//返回一个长度为i数组
return Arrays.copyOf(r, i);
} else {
//如果数组r不是传入进来的数组a,并且迭代期间有集合元素被删除,传入进来的数组a长度大于i,即数组a能够存放这些元素,将数组r的元素copy到数组a中
System.arraycopy(r, 0, a, 0, i);
//如果传入进来a的数组长度大于i
if (a.length > i) {
//将i位置元素置为null
a[i] = null;
}
}
//返回传入进来的数组
return a;
}
//将迭代器的下一个元素赋值给数组下标为i的位置
r[i] = (T)it.next();
}
// //如果在迭代将元素赋值给数组的期间,有元素添加到集合中,调用finishToArray将新增的元素加到集合中,finishToArray方法下面进行介绍,否则直接返回数组
return it.hasNext() ? finishToArray(r, it) : r;
}
/**
* 新建数组的最大大小.
* 尝试更大的数组分配可能导致内存不足错误:请求的数组大小超过vm限制
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 重新分配的数组,返回的迭代器比预期更多的元素,并从迭代器完成填充它.
*
* @param r 存储了以前的一些元素
* @param it 在这个集合正在进行的迭代器
* @return 数组包含给到的数组中的元素,并且加入迭代器新增的元素
*/
@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) {
//数组大小扩容0.5倍
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();
}
// 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");
//如果需扩容的数组大小大于允许最大的MAX_ARRAY_SIZE大小,扩容的数组大小为Integer.MAX_VALUE,否则为MAX_ARRAY_SIZE
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
// 修改操作
/**
* {@inheritDoc}
*
* <p>默认实现直接抛出
* <tt>UnsupportedOperationException</tt>异常.
*
* @throws UnsupportedOperationException 如果 <tt>add</tt> 操作
* 在这个集合不支持
* @throws ClassCastException 如果指定元素的类型不是集合元素类型的超类
* @throws NullPointerException 如果指定元素是null,并且这个集合不允许添加null元素
* @throws IllegalArgumentException 如果指定元素的某些属性可以防止它被添加到这个集合中
* @throws IllegalStateException 如果元素不能被添加由于插入的限制
*/
public boolean add(E e) {
//抛出UnsupportedOperationException异常
throw new UnsupportedOperationException();
}
/**
* <p>这个实现遍历集合寻找指定的元素。如果找到元素,从集合中删除该元素使用迭代器的删除方法
*
* <p>注意,此实现抛出一个<tt>UnsupportedOperationException</tt>
* <tt>UnsupportedOperationException</tt> .
*
* @throws ClassCastException 如果指定元素的类型与这个集合不相容
* @throws NullPointerException 如果指定元素是null,并且这个集合不允许添加null元素
* @throws UnsupportedOperationException 如果这个集合不支持删除操作
*/
public boolean remove(Object o) {
//获取迭代器
Iterator<E> it = iterator();
//如果传入的指定元素为空,从集合中判断是否存在null元素,如果存在将其移除
if (o==null) {
while (it.hasNext()) {
if (it.next()==null) {
it.remove();
return true;
}
}
} else {
//如果传入的指定元素非null,从集合中判断是否和此元素相等,如果存在将其移除
while (it.hasNext()) {
if (o.equals(it.next())) {
it.remove();
return true;
}
}
}
return false;
}
// 批量操作
/**
* 返回 <tt>true</tt> 如果集合包含指定集合的所有元素.
*
* @param c 指定集合将被检查,指定集合所有元素是否在这个集合内
* @return 返回<tt>true</tt> 如果集合包含指定集合的所有元素
* @throws ClassCastException 在指定集合中有一个或多个元素的类型和这个集合不相容
* @throws NullPointerException 如果指定集合包含一个或者多个null元素并且当前集合不允许null元素,
* @see #contains(Object)
*/
public boolean containsAll(Collection<?> c) {
for (Object e : c)
if (!contains(e))
return false;
return true;
}
/**
* 遍历指定的集合,将每一个对象添加到这个集合
*
* 注意这个实现将抛出一个UnsupportOperationException异常,除非<tt>add</tt>被重写(并且假设指定的集合是非空)
* @throws UnsupportedOperationException 如果 <tt>addAll</tt> 操作
* 在这个集合不支持
* @throws ClassCastException 如果指定元素的类型与这个集合不相容
* @throws NullPointerException 如果指定的集合含有null元素,但当前集合不支持null元素
* 或者指定的集合是null
* @throws IllegalArgumentException 如果指定中至少有一个元素的某些属性可以防止它被添加到这个集合中
* @throws IllegalStateException 如果元素不能被添加由于插入的限制
* @see #add(Object)
*/
public boolean addAll(Collection<? extends E> c) {
//是否修改标识
boolean modified = false;
//遍历传入进来的指定集合
for (E e : c)
//将传入进来的指定集合的每个元素添加到这个集合中
if (add(e))
//修改标识置为true
modified = true;
return modified;
}
/**
* 这个实现遍历指定集合,检查这个集合迭代器返回的元素是否包含在指定的集合。如果包含,从这个集合的迭代器<tt>remove</tt>方法删除这个元素
* 注意,这个实现将抛出一个异常<tt>UnsupportedOperationException</tt>异常,如果iterator()方法
* 返回的迭代器没有实现<tt>remove</tt>方法,并且这个集合包含一个或者多个指定集合的元素
* @throws UnsupportedOperationException 如果 <tt>removeAll</tt> 方法
* 在这个集合不支持
* @throws ClassCastException 如果指定集合含有一个或多个元素的类型与这个集合不相容
* @throws NullPointerException 如果指定的集合含有null元素,但当前集合不支持null元素
* 或者指定的集合是null
* @see #remove(Object)
* @see #contains(Object)
*/
public boolean removeAll(Collection<?> c) {
//传入的指定迭代器不能为空
Objects.requireNonNull(c);
//是否修改标识
boolean modified = false;
//返回这个集合迭代器
Iterator<?> it = iterator();
//判断迭代器是否有下一个元素
while (it.hasNext()) {
//判断迭代器的当前元素是否包含在指定的集合中,如果包含调用迭代器的remove方法将这个元素从集合移除
if (c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
/**
* 这个实现遍历这个集合,检查每个迭代器返回的元素是否包含在指定的集合。如果不包含,调用迭代器的<tt>remove</tt>的删除方法将这个元素移除
* 注意这个实现将抛出一个异常<tt>UnsupportedOperationException</tt>异常,如果iterator()方法
* 返回的迭代器没有实现<tt>remove</tt>方法,并且这个集合包含一个或多个元素不在指定的集合中
* @throws UnsupportedOperationException 如果 <tt>retainAll</tt> 操作
* 在这个集合不被支持
* @throws ClassCastException 如果指定集合含有一个或多个元素的类型与这个集合不相容
* @throws NullPointerException 如果指定的集合含有null元素,但当前集合不支持null元素
* 或者指定的集合是null
* @see #remove(Object)
* @see #contains(Object)
*/
public boolean retainAll(Collection<?> c) {
//传入的指定迭代器不能为空
Objects.requireNonNull(c);
//是否修改标识
boolean modified = false;
//返回这个集合迭代器
Iterator<E> it = iterator();
//判断迭代器是否有下一个元素
while (it.hasNext()) {
//判断迭代器的当前元素是否包含在指定的集合中,如果不包含调用迭代器的remove方法将这个元素从集合移除
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
/**
* 这个实现遍历这个集合,使用迭代器<tt>remove</tt>方法删除每个元素。大多数实现会选择覆盖这个方法
* 注意这个实现将抛出一个异常<tt>UnsupportedOperationException</tt>异常,如果iterator()方法
* 返回的迭代器没有实现<tt>remove</tt>方法,并且这个集合不为空
*
* @throws UnsupportedOperationException 如果 iterator不支持<tt>remove</tt> 操作
*/
public void clear() {
//返回这个集合迭代器
Iterator<E> it = iterator();
//判断迭代器是否有下一个元素
while (it.hasNext()) {
it.next();
it.remove();
}
}
// String conversion
public String toString() {
//返回这个集合的迭代器
Iterator<E> it = iterator();
//如果集合没有元素,返回[]
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
//[开头
sb.append('[');
for (;;) {
//迭代器获取下一个元素
E e = it.next();
//如果集合包含自身,这个元素使用(this Collection)代替
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
}