List 是 Collection 的子接口之一,其特性为:有序元素可重复

类注释

注释:

An ordered collection (also known as a sequence). The user of this interface has precise (adj.精确)control over where in the list each element is inserted. The user can access elements by their integer index (position in the list), and search for elements in the list.

翻译:

List 是一个有序集合,用户可以精确控制元素的插入位置,也可以通过索引访问元素,并且可以在列表中搜索元素。

特性1:有序

特性2:可以精确控制元素插入位置(通过 index)

特性3:既然可以控制插入位置,也就可以通过 index 索引精确访问元素

注释:

Unlike sets, lists typically allow duplicate elements. More formally(adv.正式地), lists typically allow pairs of elements e1 and e2 such that e1.equals(e2), and they typically allow multiple null elements if they allow null elements at all. It is not inconceivable that someone might wish to implement a list that prohibits(禁止) duplicates, by throwing runtime exceptions when the user attempts to insert them, but we expect this usage to be rare.

翻译:

Set 不同,List 允许集合中存在重复地元素,正式来说就是 List 允许集合中存在成对的 e1、e2元素,并且 e1.equals(e2)。并且如果具体 List 实现允许集合中存在 null 元素,则 List 中可以存在多个 null 元素。可能有人会希望通过抛出运行时异常来禁止 List 中存在重复地元素,但是我们并不推荐这样做

关键点:

  1. 允许存在重复元素
  2. 根据实现不同,如果允许存在 null ,则可能存在多个 null
  3. 不建议通过抛出异常的形式来强行控制 List 中不存在重复元素。

注释:

The List interface places additional stipulations(规定), beyond those specified in the Collection interface, on the contracts of the iterator, add, remove, equals, and hashCode methods. Declarations for other inherited methods are also included here for convenience.

翻译:

List 接口除了 Collection 接口中指定的规定之外,还对 迭代器(iterator)、addremoveequalshashCode 设置了其他规定,并且声明了从 Collection 中继承的其他方法。

注释:

The List interface provides four methods for positional (indexed) access to list elements. Lists (like Java arrays) are zero based. Note that these operations may execute in time proportional(按比例) to the index value for some implementations (the LinkedList class, for example). Thus, iterating over the elements in a list is typically preferable(更好地) to indexing through it if the caller does not know the implementation.

翻译:

List 接口提供了 4种 位置访问列表元素的方法。 List 的索引从0开始【因为底层是数组】,对于某些实现(例如 LinkedList)这些操作【查询操作】可能在事件上与索引值成比例执行。【元素越多,查询时间越长】。 因此,如果调用者不知道 List 的具体实现,遍历列表元素比使用索引访问元素更加可取。

注释:

The List interface provides a special iterator, called a ListIterator, that allows element insertion and replacement, and bidirectional(双向) access in addition to the normal operations that the Iterator interface provides. A method is provided to obtain(获得) a list iterator that starts at a specified position in the list.

翻译:

List 接口提供了特殊的迭代器 —— ListIterator,这个迭代器进行了功能的增强,除了支持 Iterator 的常规操作,还提供了元素插入替换以及双向访问。提供了一种从指定位置(specified position)获取 ListIterator 的方法。

注释:

The List interface provides two methods to search for a specified object. From a performance standpoint, these methods should be used with caution. In many implementations they will perform costly linear searches.

List 接口提供了两种搜索指定对象的方法,从性能角度来看,应该谨慎使用,因为在很多实现中提供的是 线性搜索,较为消耗性能。

注释:

The List interface provides two methods to efficiently insert and remove multiple elements at an arbitrary(任意) point in the list.
Note: While it is permissible for lists to contain themselves as elements, extreme caution is advised: the equals and hashCode methods are no longer well defined on such a list.

翻译:

List 接口提供了两种可以在任意位置 删除/添加 多个元素的方法。注意:虽然列表允许将自身作为元素,但是这样的话 equalshashCode 在将自己作为元素的列表上已经不再被定义,所以需要格外小心。

关键点:

  • 将 List 自身作为元素的 List 上的 equals 和 hashCode 不再被定义,这个需要些个例子。

注释:

Some list 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.

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;

some implementations will exhibit the former behavior and some will exhibit the latter. More generally, attempting an operation on an ineligible element whose completion would not result in the insertion of an ineligible element into the list 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中的一段注释完全相同,讲的是 List 对集合中元素的限制,有的 List 限制了不能添加 null 元素,有的 List 实现限制了添加的元素类型。

如果尝试添加不符合规范的元素会抛出运行时异常,一般是 NullPointerExceptionClassCastException

如果尝试查询不符合规范地元素则可能抛出异常,也可能只返回一个 false,这根据具体地实现而定。

通常来说,尝试将不符合规范地元素添加到集合中会导致异常,也可能成功添加【这块不太理解】,这种异常在此类接口的规范中被标记为 可选异常(optional)。

下面有一个大标题:Unmodifiable List ---> 不可变 List

注释:

The List.of and List.copyOf static factory methods provide a convenient way to create unmodifiable lists. The List instances created by these methods have the following characteristics:
They are unmodifiable. Elements cannot be added, removed, or replaced. Calling any mutator method on the List will always cause UnsupportedOperationException to be thrown. However, if the contained elements are themselves mutable, this may cause the List's contents to appear to change.
They disallow null elements. Attempts to create them with null elements result in NullPointerException.
They are serializable if all elements are serializable.
The order of elements in the list is the same as the order of the provided arguments, or of the elements in the provided array.
They are value-based. Callers should make no assumptions(臆测) about the identity(特性) of the returned instances. Factories are free to create new instances or reuse existing ones. Therefore, identity-sensitive(特性敏感) operations on these instances (reference equality (==), identity hash code, and synchronization) are unreliable and should be avoided.
They are serialized as specified on the Serialized Form page.

翻译:

List.of 和 List.copyOf 这两个静态工厂方法提供了非常方便地创建不可变 List 的途径,这些方法创建的不可变 List 具有以下特征:

  • List 不可修改,元素不能被添加、移除、替换。在这种 List 上调用修改元素的方法会抛出 UnsupportedOperationException 异常,但是如果 List 中保存的元素是可变的,则 List 的内容可能发生变化【这是其中元素本身发生变化导致的】。
  • 不可变 List 不允许 null 元素存在,如果 List 中包含 null 元素,创建不可变 List 时会抛出 NullPointerException
  • 如果所有元素都是可序列化,那么这个 List 就是可序列化的。
  • 不可变 List 中元素的顺序 与 创建不可变 List 的 列表 或 数组中元素的顺序一致,【也就是创建不可变 List 并不会导致元素顺序发生变化
  • 不可变 List 基于 value调用者 不应该对返回实例的身份做任何假设。 工厂可以自由创建新的 不可变 List 实例,或重用现有实例,因此 在这些实例上调用身份敏感地操作例如 equalshashCodesynchronization 是不可靠地,应该避免。

类源码:


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

    int size();

    boolean isEmpty();

    boolean contains(Object o);

    Iterator<E> iterator();

    Object[] toArray();

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

    boolean add(E e);

    boolean remove(Object o);

    boolean containsAll(Collection<?> c);

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

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

    boolean removeAll(Collection<?> c);

    boolean retainAll(Collection<?> c);

    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    default void sort(Comparator<? super E> c) {
        Object[] a = this.toArray();
        Arrays.sort(a, (Comparator) c);
        ListIterator<E> i = this.listIterator();
        for (Object e : a) {
            i.next();
            i.set((E) e);
        }
    }

    void clear();



    boolean equals(Object o);


    int hashCode();

    E get(int index);

    E set(int index, E element);

    void add(int index, E element);

    E remove(int index);

    int indexOf(Object o);

    int lastIndexOf(Object o);

    ListIterator<E> listIterator();

    ListIterator<E> listIterator(int index);


    List<E> subList(int fromIndex, int toIndex);

    @Override
    default Spliterator<E> spliterator() {
        if (this instanceof RandomAccess) {
            return new AbstractList.RandomAccessSpliterator<>(this);
        } else {
            return Spliterators.spliterator(this, Spliterator.ORDERED);
        }
    }

 
    static <E> List<E> of() {
        return ImmutableCollections.emptyList();
    }


    static <E> List<E> of(E e1) {
        return new ImmutableCollections.List12<>(e1);
    }


    static <E> List<E> of(E e1, E e2) {
        return new ImmutableCollections.List12<>(e1, e2);
    }


    static <E> List<E> of(E e1, E e2, E e3) {
        return new ImmutableCollections.ListN<>(e1, e2, e3);
    }


    static <E> List<E> of(E e1, E e2, E e3, E e4) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4);
    }


    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5);
    }


    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
                                                e6);
    }


    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
                                                e6, e7);
    }

    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
                                                e6, e7, e8);
    }


    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
                                                e6, e7, e8, e9);
    }

 
    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
        return new ImmutableCollections.ListN<>(e1, e2, e3, e4, e5,
                                                e6, e7, e8, e9, e10);
    }

 
    @SafeVarargs
    @SuppressWarnings("varargs")
    static <E> List<E> of(E... elements) {
        switch (elements.length) { // implicit null check of elements
            case 0:
                return ImmutableCollections.emptyList();
            case 1:
                return new ImmutableCollections.List12<>(elements[0]);
            case 2:
                return new ImmutableCollections.List12<>(elements[0], elements[1]);
            default:
                return new ImmutableCollections.ListN<>(elements);
        }
    }

    
    static <E> List<E> copyOf(Collection<? extends E> coll) {
        return ImmutableCollections.listCopy(coll);
    }
}

类方法:

首先看到一串 of 我是懵逼的,貌似根据元素的数量,重载了 10 个方法,为啥要这么做呢?为啥是 10个呢? 不太懂。

其次是最基础的 添加,删除 元素的方法。

在 Java8 之后添加了 接口默认方法,这里有一个 sort 排序,这样可以分担 Collections 工具类的作用,职能划分更加清晰。

容器的功能都差不多,所以感觉也没啥特别需要拿出来说的,并且由于 List 是顶层接口,有没有具体实现,所以等分析到 List 的具体实现类之后再详细说吧。

总结:

读完 Collection 的类注释之后再来看 List 能明显感觉到读的速度加快了,收益很快就能看到,还是挺好的。

Q.E.D.

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

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