Java 集合框架简单 UML 关系梳理图:

Collection 子类:

image-20201013142938624

可以看到 Collection 是顶层接口,之前也没有好好阅读过 JDK源码(其实是看注释更重要一些,文档告诉你 how,代码告诉你 detail)

类注释

第一段:

注释: The root interface in the coolection hierachy

翻译: 集合中的顶级接口

注释: A collection represents a group of objects, know as its elemnts.

翻译: 集合中存放的是同一种类型的对象(Class 相同),称为集合的元素(elements)。

注释:Some collections allow duplicate elements and others do not.

翻译: 一些集合允许重复的元素,一些集合不允许。(不同集合的特性,比如 Set 中就不存在重复的元素,这个是否重复需要根据 equalshashcode 这两个方法来进行判定)

注释::Some are order and others unordered.

翻译: 一些集合有序,一些无序(第二个特性,是否保存了元素插入顺序,这里的顺序是元素放入集合的顺序

注释: The JDK dose not provide any direct implementations of the interface

翻译: JDK 没有提供任何 Collection 接口的直接实现

注释: it provides implementations of more specific subinterface like Set and List.

翻译: JDK 选择另起了两个子接口实现 Collections,然后去细化实现子接口。

注释: This interface is typically used to pass collections around and manipulate them where maximum generality is desired.

翻译: Collection 接口通常用于传递集合并在需要最大通用性的地方操纵它们。(顶层接口的特性,所以实现 List/Set 接口的类都可以看做 Collection 的子类)

类注释第一段小结:

类注释的第一段给 Collection 下了定义:顶层接口,并且介绍了它的两个特性:元素是否可重复,元素是否有序,这些特性根据子类自己的实现而不同。

并且 JDK 没有选择直接实现 Collection 接口,而是细分了 List 和 Set 两个子接口,再去实现 List 和 Set。

第二段:

Bags or mutisets(unordered collections that may contain duplicate elements) should implement this interface directly. ---> 可能包含重复元素的无序集合应该直接实现这个接口(为啥?)

第三段

All general-purpose Collection implementation classes(which typically implement Collection) indirectly through one of its subinterface) should provide two standard constructors ---> 所有 Collection 的通用实现类(包括其子接口的实现类)应该提供两个标准构造函数

a void(no arguments) constructor which creates an empty collection and a constructor with a single argument of type Collection which creates a new collections with the same elements as its argument. ---> 两种构造函数:一种无参构造一种入参是集合中保存的元素的类型

In effect, the latter constructor allows the user to copy any collections, producing an equivalent collection of the desired implementation type. 实际上,第二种构造函数允许用户复制任何集合,从而产生所需实现类型的等效集合。(需要找出对应的代码)

There is no way to enforce this convention(as interfaces cannot contain constructors) but all of the general-purpose Collection implementations in the Java platform libraries comply. ---> Java 中没有机制强迫执行上面的约定(2个构造函数),但是 JDK 中的所有 Collection 实现都遵循了上面的约定。

小结:

主要介绍了集合的两种构造函数。

第四段

Certain methods are specified to be optional. ---> 某些方法是可选的(不是强迫必须实现)

If a collection implementation dosen't implement a particular operation, it should define the corresponding method to throw UnsupportedOperationException ---> 如果集合的实现类没有实现某个方法,就应该在方法中抛出 不支持的操作异常。

Such methods are marked "optional operation" in method specifications of the collections interfaces. --> 这种可以选择不实现的方法在 Collections 接口的方法规范中被标记为 可选操作。

小结:某些操作是可选实现的,如果子类没有实现则需要抛出对应的异常,至于哪些是可选操作,collections 接口规范中有标记。
第五段

Some collection implementations have restrictions on the elements that they may contain. ---> 一些集合的实现类对它们所包含哪些元素可能会有对应的限制。

For example, some implementations prohibit null elements, and some have restrictions on the types of their elements. ---> 例如,一些集合不允许 null 元素的存在,而某些实现类对其元素类型进行了限制。

Attempting(尝试) to add an ineligible element throws an unchecked exception, typically NullPointerException or ClassCastException ---> 如果尝试向集合中添加不合格的元素,会引发运行时异常(空指针或类型转换错误)

Attempting to query the presence of an ineligible element may throw an exception, or it may simply return false. ---> 如果尝试在集合中查询不合格的元素,则可能引发异常,或者直接返回一个 false

some implementations will exhibit the former behavior and some will exhibit the latter. ---> 一些集合的实现类表现出前者的行为(抛出异常),一些是后者(直接返回 false)

More generally, attempting an operation on an ineligible element whose completion would not result in the insertion of an ineligible element into the collection may throw an exception or it may succeed, at the option of the implementation. ---> 通常来说,尝试向集合添加不符合规范的元素时就会导致抛出异常,或者成功将不符合规范的元素插入集合中**(存疑),这取决于集合的具体实现。

Such exceptions are marked as "optional" in the specification for this interface. ---> 这些异常在 Collection 接口规范中也是被标记为可选的。

小结:

这一段主要描述了集合对于异常元素的处理 ---> 如果向集合中插入不符合集合规范的元素,可能抛出异常,也可能成功,这取决于具体实现,抛出哪些异常则在 Collection 接口规范中被标记为 optional 可选的。

第六段:

It is up to each collection to determine its own synchronization policy. ---> 每个集合定义它们自己的同步策略

In the absence(缺席) of a stronger guarantee by the implementation, undefined behavior may result from the invocation of any method on a collection that is being mutated by another thread. ---> 如果没有使用同步机制,则发生的未定义的行为可能是由于另一个线程调用了集合的方法(改变了集合的数据)

this includes direct invocations(调用), passing the collection to a method that might perform invocations, and using an existing iterator to examine the collection. ---> 上面说的多线程环境下调用集合方法导致异常包括 ①直接调用集合的方法,②将集合传递给可能执行调用的方法,③使用迭代器遍历集合。

小结

这段主要是简单地讲了一下集合需要自己实现自己的同步策略,否则在多线程环境下会导致数据异常。

第七段:

Many methods in Collections Framework interfaces are defined in terms(依赖) of the Object#equals(Object) method. ---> Collection 集合框架中的许多方法都依赖 Object 类中的 equals 方法(equals 用来判定对象是否相同,而某些集合的特性是不添加相同的对象)

For example, the specification for the contains(Object) method says: "returns true if and only if this collection contains at least one element such that (o==null ? e==null : o.equals(e)" ---> 比如 Collection 中的 contains 方法底层就要用到 Objectequals 方法比来比较集合中是否包含传入的对象。

This specification should not be construed(臆测,解释) to imply(暗示, v.) that invoking Collection.contains with a non-null argument o will cause o.equals(e) to be invoked for any elemnt e. ---> 但是这个规范不应该被理解为暗示使用非空参数 o 调用 Collection.contains(o) 会导致遍历集合中的元素 e ,然后在每个元素上调用 o.equals(e).

Implementations are free to implement optimizations whereby the equals invocation is avoided ---> 实现可以自由地进行优化,从而避免调用 equals 调用。

for example, by first comparing the hash codes of two elemnts.(The Object.hashCode() specification gurantees that two objects with unequal hash codes cannot be equal) ---> 例如可以先比较2个对象的 哈希码,如果哈希码不同,则两个对象一定不相等。(Object.hashCode() 方法做底层支撑)

More generally, implementations of the various(各个) Collections Framework interfaces are free to take advantage of the specified behavior of underlying Object methods wherever the implementor deems it appropriate --> Collection 集合框架的接口可以自由实现并利用合适的 Object 基础方法。(例如 hashCode() 和 equals() 应该是最高频的方法)

小结:

Object 中的方法都非常重要,尤其是判断对象是否相同的 hachCode 和 equals,被拿来做集合框架的底层支撑方法。

第八段:

Some collection operations which perform recursive(递归) traversal(遍历) of the collection may fail with an exception for self-referential(自引用) instances where the collection directly or indirectly contains itself.

某些执行集合递归遍历的操作可能会失败,但自引用实例的例外情况是:集合直接或间接包含自身。

This includes the conle(),equals(),hashCode(),and toString() methods, Implementations may optionally handle the self-referential scenario(场景), however most current implementations do not do so.

这包括 conle(),equals(),hashCode(),and toString() 这些方法,集合类的实现可以有选择地处理集合自引用场景,但是当前大多数实现都没有这样做(也就是没有处理集合自引用场景)

下面有一个大标题:View Collections ---> 视图集合

Most collections manage storage for elements they contain.

大多数集合管理它们存储的元素。

By contrast(相比之下), view collections themselves do not store elements, but instead they rely on a backing collection to store the actual elements.

相比之下,视图集合并不存储实际元素,而是依靠 backing collections 来存储实际元素。(意思应该是视图集合只是真正集合的视图)

Operations that are not handleed by the view collection itself are delegated to the backing collection.

视图集合无法支持的操作会被委派给 backing collection 后备支持集合。

Examples of view collections include the wrapper collections returned by methods such as Collections.checkCollection, Collections.synchronizedCollection, and Collections.unmodifiableCollection.

举个例子,视图类集合包括:

  • Collections.checkCollection
  • Collections.synchronizedCollection,
  • Collections.unmodifiableCollection.

上面三个方法返回的对应包装器集合。第一个不知道,第二个是线程安全的 Collection --> 每个方法上都加了锁,第三个是不可变集合。

Other examples of view collections include collections that provide a different representation of the same elemnts, for example as provided by List.subList, NavigableSet.subSet, or Map.entrySet.

其他的视图类集合包括提供相同元素的不同表现形式的集合,例如:

  • List.subList
  • NavigableSet.subSet
  • Map.entrySet

Any changes made to the backing collection are visible in the view collection.

backing collection 的数据如果更改了,视图集合的数据也会发生变化。

Correspondingly(相应地), any changes made to the view collection— if changes are permitted — are written through to the backing collection.

相应地,如果视图集合允许更改,任何对视图集合的更改都会写入后备集合。【这里我的认知不同,之前一直认为视图不会影响到原本的集合,视图应该是只读的。】

Although they technically are not collections, instance of Iterator and ListIterator can also allow modifications to be written through to the backing collection, and in some cases, modifications to the backing collection will be visible to the Iterator during iteration.

迭代器也可以修改后备集合,并且在某些情况下,迭代器可以在迭代过程中看到对后备集合的修改。

小结:

这一段介绍了视图集合,其中刷新了我的认知的是修改视图集合是有可能影响到原集合的,这里需要找到具体的代码,写对应的 example code。

下面一段介绍:Unmodifiable Collections ---> 不可修改集合

Certain methods of this interface are considered "destructive(破坏的)" and are called "mutator(变异)" methods in that they modify the group of objects contained within the collections on which they operate.

这个接口的某些方法被认为是"破坏性的",并且被称为 mutator 方法,因为这些方法修改了操作它们的集合中包含的对象组(也就是集合中存储的对象?)

They can be specifed to throw UnsupportedOperationException if this collection implementation does not support the operation.

如果对应的集合实现不支持这个操作,可以抛出 UnsupportedOperationException 异常。

Such methods should (but are not required to) throw an UnsupportedOperationException if the invocation would have no effect on the collection.

如果调用方法对集合没有产生任何影响,这类方法应该(但不是必须)抛出 UnsupportedOperationException 异常。

For example, consider a collection that does not support the add operation.What will happen if the addAll method is invoked on this collection, with an empty collection as the argument?

例如,一个不支持 add 操作的集合,如果在集合上调用了 addAll 方法,并将一个空集合作为参数传入,会发生什么?

The addition of zero elements has no effect, so it is permissible for this collection simply to do nothing and not to throw an exception.

However, it is recommended that such cases throw an exception unconditionally, as throwing only in certain cases can lead to programming errors.

传入的空集合导致 add 操作无效,所以可以什么也不做,但是因为这个集合的实现是不支持 add 方法的,所以建议无条件地引发异常,因为某些情况下可能会导致编程错误。

【也就是如果集合不支持某操作,哪怕执行这个操作不会影响到集合,也应该抛出异常。】

An unmodifiable collection is a collection, all of whose mutator methods(as defined above) are specifed to throw UnsupportedOperationException.

Such a collection thus cannot be modified by calling any methods on it.

不可修改集合的 mutator 方法都会抛出 UnsupportedOperationException 异常。所以不能调用任何方法修改这类集合。

For a collection to be properly unmodifiable, any view collections derived from it must also be unmodifiable.

不可变集合的视图集合也必须不可修改、【因为之前说了,修改视图集合也会影响原集合】

For example, if a List is unmodifiable, the List returned by List.subList is also unmodifiable.

举个例子,如果一个 List 是不可变的,那么 List.subList 返回的集合也必须是不可变的。

An unmodifiable collection is not necessarily immutable. If the contained elements are mutable, the entire collection is clearly mutable, even though it might be unmodifiable.

不可修改集合(unmodifiable) 不一定是不可变的(immutable),因为如果集合中包含的元素是可变的,那么集合就是可变的,所以集合 是否可变与是否是不可修改集合不冲突。【这里的不可修改指的是元素的数量,而是否可变包含了元素的状态】

For example, consider two unmodifiable lists contaning mutable elements. The result of calling list1.equals(list2) might differ from one call to the next if the elements had been mutated, even though both lists are unmodifiable.

例如,两个不可变 list 其中存储的都是可变元素,调用 list1.equals(list2) 的结构可能因为其中存储的元素发生变化而不同(也就是有时候 true 有时候 false)。

However if an unmodifiable collection contains all immutable elements, it can be considered effctively immutable.

然而 如果两个不可修改的集合存储的都是不可变元素,可以将其看做有效不可变(effctively immutable)集合。

小结:

关于不可修改集合,与集合中保存的元素的可变性,这块还是挺复杂的。 不可修改集合不一定不可变,因为是否可变不仅取决于集合自身,还取决于其保存的元素。只有集合和保存的元素都不可变时,才说是 有效不可变的。

下面一段介绍:Unmodifiable View Collections ---> 不可修改视图集合

An unmodifiable view collection is a collection that is unmodifiable and that is also a view onto a backing collection.

不可修改的视图集合是集合的一种,它是 backing collection 的视图。

Its mutator methods throw UnsupportedOperationException, as described above, while reading and querying methods are delegated to the backing collection.

不可修改的视图集合的 mutator 方法会抛出 UnsupportedOperationException,并且 读取和查询方法会委托给原集合(backing collection)

The effect is to provide read-only access to the backing collection.

不可变视图集合的效果是提供原集合的只读访问。【这才是我印象中的视图的作用,看来我印象中的是**不可变视图集合**】

This is useful for a component to the provide users with read access to an internal collection, while preventing(防止) them from modifying such collections unexpectedly.

不可变视图集合对于向用户提供内部集合的读取访问权限,并且防止用户修改集合内容很有用。

Examples of unmodifiable view collections are those returned by the Collections.unmodifiableCollection, Collections.unmodifiableList, and related methods.

  • Collections.unmodifiableCollection
  • Collections.unmodifiableList,

返回的集合是不可修改的视图集合,以及其他相关方法返回的集合。

Note that changes to the backing collection might still be possible, and if they occur, the are visible through the unmodifiable view.

同时不可变视图集合并不能保证 backing collection 不被修改,同时如果修改了 backing collection,也可以在不可变视图集合中看到修改后的结果。

Thus, an unmodifiable view collection is not necessarily immutable.

所以,不可变视图集合并不一定是不变的 —— 如果原集合被修改了,视图也会相应的发生变化。【get 到了新的点】

However, if the backing collection of an unmodifiable view is effectively immutable, or if the only reference to the backing collection is through an unmodifiable view, the view can be considered effectively immutable.

如果不可修改的视图的原集合实际上是不可变的,或者不可变视图是原集合的唯一引用(也就是不会有别的引用操作原集合),则可以将视图视为有效不可变的。

以上就是 Collection 类的类注释,非常的常,同时信息量也很多,仿佛做完了一个长篇阅读理解,读类的注释比看一般的博客要好,因为注释一般是代码的作者写的,所以是一手的资料,信息不会在传播中损失或变化。

类方法

package java.util;

import java.util.function.IntFunction;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;


public interface Collection<E> extends Iterable<E> {

    boolean isEmpty();

    boolean contains(Object o);
rn an {@code Iterator} over the elements in this collection
     */
    Iterator<E> iterator();


    Object[] toArray();

    <T> T[] toArray(T[] a);

    default <T> T[] toArray(IntFunction<T[]> generator) {
        return toArray(generator.apply(0));
    }

    boolean add(E e);

    boolean remove(Object o);

    boolean containsAll(Collection<?> c);

    boolean addAll(Collection<? extends E> c);


    boolean removeAll(Collection<?> c);

    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;
    }

    boolean retainAll(Collection<?> c);

    void clear();

    boolean equals(Object o);


    int hashCode();
  
  /* --------------- 1.8 之后新添加的默认方法 --------------- */
    @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);
    }
}

Q.E.D.

知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议

最是人间留不住,曾是惊鸿照影来。