Java集合源码分析(六)-List

143 阅读18分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战

源码

public interface List<E> extends Collection<E> {
    // 查询操作

    /**
     * 返回这个列表元素的数量
     * 如果这个集合包含超过 Integer.MAX_VALUE 元素,返回 Integer.MAX_VALUE
     *
     * @return 这个列表元素的数量
     */
    int size();

    /**
     * 如果这个列表没有包含任何元素,返回 true
     *
     * @return 如果这个列表没有包含任何元素,true
     */
    boolean isEmpty();

    /**
     * 如果这个列表包含指定元素,返回 true
     * 更准确地说,当且仅当这个列表包含至少一个元素 e 如 (o==null && e==null && o.equals(e)),返回 true
     *
     * @param o 要测试在这个列表中是否存在的元素
     * @return <tt>true</tt> 如果这个集合包含指定元素
     * @throws ClassCastException 如果指定元素和这个列表的类型不相容
     * @throws NullPointerException 如果指定元素是 null 并且这个列表不允许 null 元素
     */
    boolean contains(Object o);

    /**
     * 返回按正确的顺序遍历这个列表的元素的迭代器
     *
     * @return 按正确的顺序遍历这个列表的元素的迭代器
     */
    Iterator<E> iterator();

    /**
     * 返回按正确顺序(从第一个到最后一个元素)包含这个列表所有元素的数组
     *
     * 返回的数组是安全的,因为这个集合不维护对它的应用(换句话说,这个方法必须分配一个新数组,即使这个集合基于数组支持)因此,调用者可以自由修改返回的数组
     *
     * 这个方法充当基于数组 API 和基于集合 API 的桥梁
     *
     * @return 按正确顺序包含这个列表所有元素的数组
     * @see Arrays#asList(Object[])
     */
    Object[] toArray();

    /**
     * 返回按正确的顺序(从第一个元素到最后一个元素)包含这个列表的全部元素的数组;返回数组的运行类型是指定数组的运行类型
     * 如果列表符合指定的数组,则返回指定的数组
     * 否则,通过指定数组的运行时类型和这个列表的大小分配一个新的数组
     *
     * 如果这个集合适合指定数组,并且有剩余空间(即,数组中的元素比这个集合中的元素多),数组中紧随集合结束的元素设置为 null
     * (只有当调用者知道这个集合没有包含任何 null 元素,才有助于确定这个集合的长度)
     *
     * 像 toArray() 方法,这个方法充当基于数组 API 和基于集合 API 的桥梁
     * 进一步的讲,这个方法允许精确控制输出数组的运行时类型,并且可能在某种情况下,用于节省分配成本
     *
     * 假设 x 是一个已知只包含字符串的集合
     * 下面的代码可以用来将集合转存到一个新分配的字符串数组中
     *
     * <pre>{@code
     *     String[] y = x.toArray(new String[0]);
     * }</pre>
     *
     * 注意 toArray(new Object[0]) 在功能上与 toArray() 是完全相同的
     *
     * @param a 如果数组足够大将此集合的元素存储到其中,否则,因为这个目的分配一个相同运行时类型的新数组
     * @return 包含这个列表元素的数组
     * @throws ArrayStoreException 如果指定数组的运行时类型不是这个列表中每个元素的运行时类型的父类
     * @throws NullPointerException 如果指定数组是 null
     */
    <T> T[] toArray(T[] a);


    // 修改操作

    /**
     * 将指定元素追加到这个列表的末尾(可选操作)
     *
     * 支持这个操作的集合可能会设置什么元素可以添加到这个集合
     * 特别是,有的集合会拒绝添加 null 元素,有的会对添加元素的类型做限制
     *
     * 列表类应该在它们的文档中清晰指明可能添加的元素的任何限制
     *
     * @param e 要追加到这个列表的元素
     * @return <tt>true</tt> (按照 Collection#add)
     * @throws UnsupportedOperationException 如果这个列表不支持 add 操作
     * @throws ClassCastException 如果指定元素的类阻止它添加到这个集合
     * @throws NullPointerException 如果指定元素是 null,并且这个集合不允许 null 元素
     * @throws IllegalArgumentException 如果元素的某些属性阻止它添加到这个集合
     */
    boolean add(E e);

    /**
     * 从这个列表移除指定元素的第一个匹配元素,如果有(可选操作)
     * 如果这个列表不包含指定元素,它不变
     * 更准确的说,删除索引最低的元素 i,例如 (o==null && get(i)==null && o.equals(get(i)))(如果这样一个元素存在)
     * 如果这个列表包含指定元素,返回 true(或者相当于,如果这个列表因为这个调用而改变)
     *
     * @param o 这个列表被移除的元素,如果存在
     * @return <tt>true</tt> 如果这个列表包含指定元素
     * @throws ClassCastException            如果指定元素的类型和这个列表的类型不相容
     * @throws NullPointerException          如果指定元素是 null,并且这个列表不支持 null 元素
     * @throws UnsupportedOperationException 如果这个列表不支持 remove 操作
     */
    boolean remove(Object o);


    // 批量修改操作

    /**
     * 返回 true,如果这个列表包含指定集合的所有元素
     *
     * @param c 检查集合是否包含在这个列表中
     * @return <tt>true</tt> 如果这个列表包含指定集合的所有元素
     * @throws ClassCastException   如果指定集合有一个或多个元素和这个列表数据类型不同
     * @throws NullPointerException 如果指定集合包含一个或多个 null 元素,并且这个列表不支持 null 元素,或者如果指定集合是 null
     * @see #contains(Object)
     */
    boolean containsAll(Collection<?> c);

    /**
     * 添加指定集合的所有元素到这个列表的尾部,按照指定集合的迭代器返回的顺序
     * 如果指定集合在操作的过程中修改,这个操作的行为不明(这意味着,如果指定集合是这个集合,并且这个集合是非空的,则会发生这种情况)
     *
     * @param c 包含要添加到这个集合的元素的集合
     * @return <tt>true</tt> 如果这个集合因为调用这个方法改变了
     * @throws UnsupportedOperationException 如果这个列表不支持 addAll 操作
     * @throws ClassCastException            如果指定集合的元素的类阻止它添加到这个列表
     * @throws NullPointerException          如果指定集合包含一个或多个 null 元素,并且这个列表不支持 null 元素,或者指定集合是 null
     * @throws IllegalArgumentException      如果指定集合的元素的某些属性阻止它添加到这个列表
     * @see #add(Object)
     */
    boolean addAll(Collection<? extends E> c);

    /**
     * 在指定索引插入指定集合的全部元素到这个列表(可选操作)
     * 将元素移动到当前位置(如果有),并且右边的任何后续元素(增加它们的索引)
     * 新元素会按照指定集合的迭代器返回的顺序出现在这个列表
     * 如果指定集合在操作的过程中修改,这个操作的行为不明(这意味着,如果指定集合是这个集合,并且这个集合是非空的,则会发生这种情况)
     *
     * @param index 从指定集合中插入第一个元素的索引
     * @param c     包含要添加到这个集合的元素的集合
     * @return <tt>true</tt> 如果这个集合因为调用这个方法改变了
     * @throws UnsupportedOperationException 如果这个列表不支持 addAll 操作
     * @throws ClassCastException            如果指定集合的元素的类阻止它添加到这个列表
     * @throws NullPointerException          如果指定集合包含一个或多个 null 元素,并且这个列表不支持 null 元素,或者指定集合是 null
     * @throws IllegalArgumentException      如果指定集合的元素的某些属性阻止它添加到这个列表
     * @throws IndexOutOfBoundsException     如果索引超出范围 index < 0 || index > size()
     */
    boolean addAll(int index, Collection<? extends E> c);

    /**
     * 从这个列表移除指定集合包含的所有元素(可选操作)
     *
     * @param c 包含要从这个列表移除的元素的集合
     * @return <tt>true</tt> 如果这个集合因为调用这个方法改变了
     * @throws UnsupportedOperationException 如果这个列表不支持 removeAll 操作
     * @throws ClassCastException            如果这个列表的元素的类与指定集合的类不相容
     * @throws NullPointerException          如果这个列表包含 null 元素,并且指定集合不支持 null 元素,或者指定集合是 null
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean removeAll(Collection<?> c);

    /**
     * 只保留在这个集合中包含在指定集合中的元素(可选操作)
     * 换句话说,从这个集合移除所有不包含在指定集合的元素
     *
     * @param c 包含要保留在这个列表中的元素的集合
     * @return <tt>true</tt> 如果这个集合因为调用这个方法改变了
     * @throws UnsupportedOperationException 如果这个列表不支持 retainAll 操作
     * @throws ClassCastException            如果这个列表的元素的类与指定集合的类不相容
     * @throws NullPointerException          如果这个列表包含 null 元素,并且指定集合不支持 null 元素,或者指定集合是 null
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean retainAll(Collection<?> c);

    /**
     * 使用这个列表的每一个元素通过运算的结果代替本身
     * 操作者抛出的错误或者运行时异常转发给调用者
     *
     * @param operator 应用于每一个元素的操作
     * @throws UnsupportedOperationException 如果这个列表是不可修改的 if this list is unmodifiable.
     *                                       如果不能替换元素,或者如果不支持修改,实现可能抛出这个异常
     * @throws NullPointerException          如果指定操作是 null 或者这个操作结果是 null 值,并且这个列表不允许 null 元素
     * 对于这个列表默认实现相当于:
     * <pre>{@code
     *     final ListIterator<E> li = list.listIterator();
     *     while (li.hasNext()) {
     *         li.set(operator.apply(li.next()));
     *     }
     * }</pre>
     * <p>
     * 如果列表的列表迭代器不支持 set 操作,然后在替换第一个元素时抛出 UnsupportedOperationException
     * @since 1.8
     */
    default void replaceAll(UnaryOperator<E> operator) {
        Objects.requireNonNull(operator);
        final ListIterator<E> li = this.listIterator();
        while (li.hasNext()) {
            li.set(operator.apply(li.next()));
        }
    }

    /**
     * 根据指定比较器产生的顺序对这个列表进行排序
     *
     * 这个列表的所有元素必须使用指定比较器相互比较(就是对于列表中任何元素 e1 和 e2,c.compare(e1, e2) 必须抛出 ClassCastException)
     *
     * 如果指定比较器是 null ,然后这个列表的全部元素必须实现 Comparable 接口和应该使用元素的可比自然顺序
     *
     * 这个列表必须是可修改的,但不需要可调整大小
     *
     * @param c 用于比较列表元素的比较器
     *          null 值表示应该使用元素的可比自然顺序
     * @throws ClassCastException            如果列表包含使用指定比较器无法相互比较的元素
     * @throws UnsupportedOperationException 如果列表的列表迭代器不支持 set 操作
     * @throws IllegalArgumentException      如果比较器被发现违反比较器合约
     * 默认实现获取一个包含这个列表全部元素的数组,对数组进行排序,并且编列这个列表,从数组相应的位置重置每个元素(这避免了由于尝试对链表列表进行排序而产生的 n^2log(n) 性能)
     * 这个实现是一种稳定的、自适应的、迭代的合并排序,当输入数组是部分有序时需要远少于 nlg(n) 比较,当输入数组随机排序时提供了传统合并请求的性能
     * 如果输入数组几乎是有序时,实现要求大约 n 次比较
     * 临时存储要求各不相同,从几乎排序的输入数组的一个小常量到随机排序的输入数组的n/2对象引用
     *
     * 实现同样利用了输入数组的升序和降序,并且能够利用相同输入数组的不同部分的升序和降序
     * 它非常适合合并两个或多个已排序的数组:只连接数组和结果数组进行排序
     *
     * 实现根据 Tim Peters 的 Python TimeSort 列表排序改写
     * 它使用的技术来自 Peter McIlroy 的 "Optimistic Sorting and Information Theoretic Complexity"
     * 《Proceedings of the Fourth Annual ACM-SIAM Symposium on Discrete Algorithms》,第 467-474 页,1993 年 1 月
     * @since 1.8
     */
    @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);
        }
    }

    /**
     * 从这个列表移除全部元素(可选操作)
     * 这个调用返回后,这个列表将变成空
     *
     * @throws UnsupportedOperationException 如果这个列表不支持 clear 操作
     */
    void clear();


    // 比较和散列

    /**
     * 比较指定对象和这个列表进行相等比较
     *
     * 当且仅当指定对象同样是一个列表,两个列表有相同大小,并且两个列表相应部分的元素都相等,返回 true(两个对象 e1 和 e2 是相等,如果 (e1==null ? e2==null :e1.equals(e2)))
     * 换句话说,两个列表定义相同,如果它们以相同顺序包含相同元素
     * 这定义确保了 equals 方法在 List 接口的不同实现正常工作
     *
     * @param o 要与这个列表进行相等对比的对象
     * @return <tt>true</tt> 如果指定对象与这个列表相等
     */
    boolean equals(Object o);

    /**
     * 返回这个列表的哈希码值
     * 列表的哈希码定义为以下计算的结果
     * <pre>{@code
     *     int hashCode = 1;
     *     for (E e : list)
     *         hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
     * }</pre>
     * 对于任何两个列表 list1 和 list2,确保了 list1.equals(list2) 意味着 list1.hashCode()==list2.hashCode(),按照 Object#hashCode 的普遍合约要求
     *
     * @return 这个列表的哈希码值
     * @see Object#equals(Object)
     * @see #equals(Object)
     */
    int hashCode();


    // 位置访问操作

    /**
     * 返回这个列表指定索引的元素
     *
     * @param index 要返回元素的索引
     * @return 在这个列表中指定索引的元素
     * @throws IndexOutOfBoundsException 如果索引超出范围 index < 0 || index > size()
     */
    E get(int index);

    /**
     * 使用指定元素代替这个列表指定索引的元素(可选操作)
     *
     * @param index 要代替元素的索引
     * @param element 要被存储在指定索引的元素
     * @return 之前在指定索引的元素
     * @throws UnsupportedOperationException 如果这个列表不支持 set 操作
     * @throws ClassCastException 如果指定元素的类阻止它添加到这个列表
     * @throws NullPointerException 如果指定元素是 null,并且这个列表不支持 null 元素
     * @throws IllegalArgumentException 如果指定元素的一些属性阻止它添加到这个列表
     * @throws IndexOutOfBoundsException 如果索引超出范围 index < 0 || index > size()
     */
    E set(int index, E element);

    /**
     * 在这个列表的指定索引插入指定元素(可选操作)
     * 将元素移动到当前位置(如果有),并且右边的任何后续元素(给它们索引加一)
     *
     * @param index 要插入元素的索引
     * @param element 要插入的元素
     * @throws UnsupportedOperationException 如果这个列表不支持 add 操作
     * @throws ClassCastException 如果指定元素的类阻止它添加到这个列表
     * @throws NullPointerException 如果指定元素是 null,并且这个列表不支持 null 元素
     * @throws IllegalArgumentException 如果指定元素的一些属性阻止它添加到这个列表
     * @throws IndexOutOfBoundsException 如果索引超出范围 index < 0 || index > size()
     */
    void add(int index, E element);

    /**
     * 移除这个列表指定索引的元素(可选操作)
     * 将任何后续的元素向左移(从它们的索引减一)
     * 返回被列表移除的元素
     *
     * @param index 要移除元素的索引
     * @return 之前在指定索引的元素
     * @throws UnsupportedOperationException 如果这个列表不支持 remove 操作
     * @throws IndexOutOfBoundsException 如果索引超出范围 index < 0 || index > size()
     */
    E remove(int index);


    // 查询操作

    /**
     * 返回指定元素在这个列表第一次出现的索引,或者如果这个列表没有包含这个元素,则返回 -1
     * 更正确的说,返回最低索引 i,例如 (o==null && get(i)==null && o.equals(get(i))),如果这里没有这样的索引,返回 -1
     *
     * @param o 要搜索的元素
     * @return 指定元素在这个列表第一次出现的索引,或者如果这个列表没有包含这个元素,则 -1
     * @throws ClassCastException 如果指定元素的类型与这个列表不相容
     * @throws NullPointerException 如果指定元素是 null,并且这个列表不支持 null 元素
     */
    int indexOf(Object o);

    /**
     * 返回指定元素在这个列表最后一次出现的索引,或者如果这个列表没有包含这个元素,则返回 -1
     * 更正确的说,返回最高索引 i,例如 (o==null && get(i)==null && o.equals(get(i))),如果这里没有这样的索引,返回 -1
     *
     * @param o 要搜索的元素
     * @return 指定元素在这个列表最后一次出现的索引,或者如果这个列表没有包含这个元素,则 -1
     * @throws ClassCastException 如果指定元素的类型与这个列表不相容
     * @throws NullPointerException 如果指定元素是 null,并且这个列表不支持 null 元素
     */
    int lastIndexOf(Object o);


    // 列表迭代器

    /**
     * 返回这个列表中元素的列表迭代器(按正确的顺序)
     *
     * @return 这个列表中元素的列表迭代器(按正确的顺序)
     */
    ListIterator<E> listIterator();

    /**
     * 返回这个列表中元素的爹表迭代器(按正确的顺序),从列表的指定索引开始
     * 指定索引表明初始调用 ListIterator#next 将返回的第一个元素
     * 初始化调用 ListIterator#previous 将返回指定索引为 -1 的元素
     *
     * @param index 从列表迭代器返回的第一个元素的索引(调用 ListIterator#next)
     * @return 这个列表中元素的列表迭代器(按正确的顺序), 从列表的指定索引开始
     * @throws IndexOutOfBoundsException 如果索引超出范围 index < 0 || index > size()
     */
    ListIterator<E> listIterator(int index);

    // 看

    /**
     * 返回这个列表指定从 fromIndex(包括) 到 toIndex(不包括)区域之间部分的视图(如果 fromIndex 和 toIndex 相等,返回的列表是空)
     * 返回的列表是基于这个列表,所以返回列表的非结构性改变会反射到这个列表中,反之亦然
     * 返回的列表支持这个列表支持的全部可选列表操作
     *
     * 这个方法不需要明确操作范围(数组通常存在的那种)
     * 通过传递子列表视图而不是整个列表,任何需要列表操作可以被用作范围操作
     * 例如,下面的语法从列表移除一系列元素
     * <pre>{@code
     *      list.subList(from, to).clear();
     * }</pre>
     * 类似的语法也可用于 indexOf 和 lastIndexOf,和 Collections 类的全部算法能够应用于子列表
     *
     * 如果支持列表(即,这个列表)在结构上改变,而不是通过返回的列表,这个方法返回的列表的语义变成未定义(结构改变会改变列表的大小,或者用某种方式干扰它,正在迭代可能产生错误的结果
     *
     * @param fromIndex 子列表的起点(包括)
     * @param toIndex 子列表的终点(不包括)
     * @return 这个列表指定范围的视图
     * @throws IndexOutOfBoundsException 非法的端点索引值(fromIndex < 0 || toIndex > size || fromIndex > toIndex)
     */
    List<E> subList(int fromIndex, int toIndex);

    /**
     * 创建这个列表元素的分离器 
     * 分离器报告 Spliterator#SIZED 和 Spliterator#ORDERED
     * 实现应该记录额外特征值的报告
     *
     * 默认实现从列表的迭代器创建一个延迟绑定分离器
     * 分离器继承了列表迭代器的快速失败属性
     *
     * 创建的分离器额外报告 Spliterator#SUBSIZED
     *
     * @return 这个列表元素的分离器
     * @since 1.8
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, Spliterator.ORDERED);
    }
}

总结

  • 查询操作
    • int size():返回这个列表元素的数量
    • boolean isEmpty():如果这个列表没有包含任何元素,返回 true
    • 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):使用这个列表的每一个元素通过运算的结果代替本身
    • default void sort(Comparator<? super E> c):根据指定比较器产生的顺序对这个列表进行排序
    • 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):返回这个列表指定从 fromIndex(包括) 到 toIndex(不包括)区域之间部分的视图(
    • default Spliterator<E> spliterator():创建分离器