【java】Collection源码阅读(JDK 8)

没有人挡得住,你疯狂的努力进取。你可以不够强大,但你不能没有梦想。如果你没有梦想,你只能为别人的梦想打工筑路。

导读:本篇文章讲解 【java】Collection源码阅读(JDK 8),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在这里插入图片描述

package java.util;
 
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
 
/**
 * 集合层次结构的根接口,一个集合表示一组对象,称为元素
 * JDK不提供任何该接口的直接实现,JDK提供实现特定情况的子接口,Set,List
 *
 * 所有通用Collection实现类通常需要通过一个间接实现Collection接口的子接口来实现,
 * 而且需要提供两个标准的构造函数,没有参数的构造函数(空参构造),创建一个空集合;
 * 以及包含Collection类型的单个参数的构造函数,使用与其参数相同的元素创建一个新集合。
 * @author  Josh Bloch
 * @author  Neal Gafter
 * @see     Set
 * @see     List
 * @see     Map
 * @see     SortedSet
 * @see     SortedMap
 * @see     HashSet
 * @see     TreeSet
 * @see     ArrayList
 * @see     LinkedList
 * @see     Vector
 * @see     Collections
 * @see     Arrays
 * @see     AbstractCollection
 * @since 1.2
 */
public interface Collection<E> extends Iterable<E> {
    // 查询操作
 
    /**
     * 返回此集合中的元素数。如果这个集合 包含多于<tt> Integer.MAX_VALUE </ tt>的元素,返回 <tt> Integer.MAX_VALUE </ tt>。
     *
     * @return 此集合中的元素数量
     */
    int size();
 
    /**
     * 如果此集合不包含任何元素,则返回<tt> true </ tt>
     * @return <tt>true</tt> 如果此集合不包含任何元素
     */
    boolean isEmpty();
 
    /**
     *
     * 如果集合中包含至少一个指定对象,返回true
     * @param o 要测试其在此集合中的存在的元素
     * @return <tt>true</tt>  如果集合中包含该元素
     *
     * @throws ClassCastException 如果指定元素的类型 与集合内元素类型不兼容
     * @throws NullPointerException 如果指定的元素为null且此 collection不允许null元素
     *
     */
    boolean contains(Object o);
 
    /**
     * 返回此集合中元素的迭代器。无法保证元素的返回顺序
     *(除非此集合是某个提供保证的类的实例)。
     *
     * @return an <tt>Iterator</tt> 覆盖此集合中的元素
     */
    Iterator<E> iterator();
 
    /**
     * 返回包含此集合中所有元素的数组。
     * 如果此集合对其迭代器返回的元素的顺序做出任何保证,则此方法必须以相同的顺序返回元素。
     *
     * 返回的数组将是“安全的”,因为此集合不会保留对它的引用。
     * (换句话说,即使此集合由数组支持,此方法也必须分配新数组)。
     *  调用者因此可以自由修改返回的数组。
     *
     * @return 包含此集合中所有元素的数组
     */
    Object[] toArray();
 
    /**
     * 返回包含此集合中所有元素的数组;
     * 返回数组的运行时类型是指定数组的运行时类型。
     * 如果集合适合指定的数组,则返回元素到指定的数组中。
     * 否则,将使用指定数组的运行时类型和此集合的大小分配新数组。
     *
     * 此集合适合指定的数组,如果有空余空间(即,数组的元素多于此集合),则紧跟集合结尾的数组中的元素将设置为<tt> null </ TT>。
     * (如果调用者知道此集合不包含任何<tt> null </ tt>元素,则此选项仅用于确定此集合的长度<i> </ i>。)
     *
     * 如果此集合对其迭代器返回的元素的顺序做出任何保证,则此方法必须以相同的顺序返回元素。
     *
     * @param <T> 包含集合的数组的运行时类型
     * @throws ArrayStoreException 如果指定数组的运行时类型不是此集合中每个元素的运行时类型的超类型
     * @throws NullPointerException 如果指定的数组为null
     */
    <T> T[] toArray(T[] a);
 
    // 修改操作
 
    /**
     * 将元素e添加到集合中
     * 如果集合不允许重复元素,且集合中已经含有该元素,返回false
     * false-添加失败
     */
    boolean add(E e);
 
    /**
     * 从该 collection 中移除指定元素的单个实例,如果集合中存在指定元素返回true。
     */
    boolean remove(Object o);
 
 
    // 批量操作
 
    /**
     * 如果此 collection 包含指定 collection 中的所有元素,则返回 true。
     */
    boolean containsAll(Collection<?> c);
 
    /**
     * 将指定 collection 中的所有元素都添加到此 collection 中
     */
    boolean addAll(Collection<? extends E> c);
 
    /**
     * 移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
     */
    boolean removeAll(Collection<?> c);
 
    /**
     *
     * 删除此集合中满足给定布尔值函数的所有元素。在迭代期间或通过布尔值函数抛出的错误或运行时异常被中继到调用者。
     * 默认使用迭代器进行删除元素
     *
     * @param filter 一个布尔值函数,它返回{@code true}表示要删除的元素
     * @return {@code true} 如果删除了任何元素
     * @since 1.8
     */
    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);
 
    /**
     * 移除此 collection 中的所有元素。
     */
    void clear();
 
 
    // 比较和散列
 
    /**
     *  比较此 collection 与指定对象是否相等。通过覆盖,实现list与list相等,set与set相等
     */
    boolean equals(Object o);
 
    /**
     * 返回此 collection 的哈希码值。
     */
    int hashCode();
 
    /**
     *
     * Spliterator是一个可分割迭代器(splitable iterator),可以和iterator顺序遍历迭代器一起看。jdk1.8发布后,对于并行处理的能力大大增强,Spliterator就是为了并行遍历元素而设计的一个迭代器,jdk1.8中的集合框架中的数据结构都默认实现了spliterator
     *
     * 在此集合中的元素上创建{@link Spliterator}。
     *
     * 后续如果讲到了{@link Spliterator}再进行补充下面的三个方法
     *
     *
     * Implementations should document characteristic values reported by the
     * spliterator.  Such characteristic values are not required to be reported
     * if the spliterator reports {@link Spliterator#SIZED} and this collection
     * contains no elements.
     *
     * <p>The default implementation should be overridden by subclasses that
     * can return a more efficient spliterator.  In order to
     * preserve expected laziness behavior for the {@link #stream()} and
     * {@link #parallelStream()}} methods, spliterators should either have the
     * characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be
     * <em><a href="Spliterator.html#binding">late-binding</a></em>.
     * If none of these is practical, the overriding class should describe the
     * spliterator's documented policy of binding and structural interference,
     * and should override the {@link #stream()} and {@link #parallelStream()}
     * methods to create streams using a {@code Supplier} of the spliterator,
     * as in:
     * <pre>{@code
     *     Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
     * }</pre>
     * <p>These requirements ensure that streams produced by the
     * {@link #stream()} and {@link #parallelStream()} methods will reflect the
     * contents of the collection as of initiation of the terminal stream
     * operation.
     *
     * @implSpec
     * The default implementation creates a
     * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
     * from the collections's {@code Iterator}.  The spliterator inherits the
     * <em>fail-fast</em> properties of the collection's iterator.
     * <p>
     * The created {@code Spliterator} reports {@link Spliterator#SIZED}.
     *
     * @implNote
     * The created {@code Spliterator} additionally reports
     * {@link Spliterator#SUBSIZED}.
     *
     * <p>If a spliterator covers no elements then the reporting of additional
     * characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED},
     * does not aid clients to control, specialize or simplify computation.
     * However, this does enable shared use of an immutable and empty
     * spliterator instance (see {@link Spliterators#emptySpliterator()}) for
     * empty collections, and enables clients to determine if such a spliterator
     * covers no elements.
     *
     * @return a {@code Spliterator} over the elements in this collection
     * @since 1.8
     */
    @Override
    default Spliterator<E> spliterator() {
        return Spliterators.spliterator(this, 0);
    }
 
    /**
     * Returns a sequential {@code Stream} with this collection as its source.
     *
     * <p>This method should be overridden when the {@link #spliterator()}
     * method cannot return a spliterator that is {@code IMMUTABLE},
     * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
     * for details.)
     *
     * @implSpec
     * The default implementation creates a sequential {@code Stream} from the
     * collection's {@code Spliterator}.
     *
     * @return a sequential {@code Stream} over the elements in this collection
     * @since 1.8
     */
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
 
    /**
     * Returns a possibly parallel {@code Stream} with this collection as its
     * source.  It is allowable for this method to return a sequential stream.
     *
     * <p>This method should be overridden when the {@link #spliterator()}
     * method cannot return a spliterator that is {@code IMMUTABLE},
     * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
     * for details.)
     *
     * @implSpec
     * The default implementation creates a parallel {@code Stream} from the
     * collection's {@code Spliterator}.
     *
     * @return a possibly parallel {@code Stream} over the elements in this
     * collection
     * @since 1.8
     */
    default Stream<E> parallelStream() {
        return StreamSupport.stream(spliterator(), true);
    }
}

Collection

type: interface

public interface Collection extends Iterable

类文档

该接口是集合大类中的根接口。一个集合代表着一组对象,该对象被称为元素。一些集合允许重复的元素,而另一些集合不允许。一些集合是有序的,另一些是无序的。JDK不提供任何该接口的直接实现:提供了更具体的子类的实现,如:Set、List。该接口提供了最大程度的通用性用于操作和抽象的表示集合。

原文中为:This interface is typically used to pass collections around and
manipulate them where maximum generality is desired.
机器翻译为:该接口通常用于传递集合并操作它们,其中需要最大的通用性。 但是我认为 pass collections around
翻译成传递不好,我翻译为抽象或者表示。

背包(bags:一种数据结构 类似栈)和多集(multisets:一种数据结构 无序且允许元素重复)应该直实现承该接口。

所有通用的Collection实现类(通常是实现Collection的子接口)应该提供梁总标准的构造方法:
一个是空参的构造方法:该方法创建一个空集合,
另一个是具有一个Collection类型参数的构造方法,使用具有参数的元素进行创建。
实际上,第二种构造方法允许用户复制任意集合来生成目标类型的等效集合。
当然,没有任何方法保证强制执行这个约定(Collection是一个接口,接口中不能包含构造函数)
但是Java平台内所有的通用Collection的实现类都是符合上述约定的。

在这个接口中有一些“破坏性”的方法,
当调用某种集合不支持的操作进行修改集合的时候会抛出(UnsupportedOperationException java.lang包下)
如果操作被调用后对集合本身没有影响,这种情况下可以但不是必须要抛出该异常。
例如:对不可修改的集合调用addAll(Collection)方法添加空集可以引发该异常,但不是必须的。
(注意这里是添加空集合,表示不添加任何数据,所以没有影响,如果是添加有数据的集合,那就要抛出异常)

Collection的一些实现类限制他包含的元素。
例如:一些实现类禁制null元素,还有一些实现类限制元素的数据类型。
如果尝试添加一个不支持的类型将会抛出UncheckedException,例如空指针异常(NullPointerException),类强制转换异常(ClassCaseException)。
如果尝试查询一个不合法的元素可能会抛出异常,或者仅仅是返回false.
通俗来说,对于尝试使用一个非法元素去操作集合,但是对结果没有任何影响时,有可能会抛出异常,也有可能顺利执行该方法。
此部分在接口的规范中标记为’可选’。

由每种集合自行决定他们自己的同步策略。
在没有有力的保障下的实现类,未知的行为来自该集合的一些方法被其他线程调用导致的数据改变。
包括直接调用、将集合传递给可能执行调用的方法、使用现有迭代器检索集合。

在集合框架接口下的一些方法都是根据equals方法定义的。但是这并不代表制真的就是使用这个方法。
子类自由决定使用更加优化的方法,进而笔迷使用equals。
参考contains(Object o);方法
更一般地说,各种集合框架接口的实现可以自由地利用底层对象方法的指定行为,只要实现者认为合适。

对于自引用的集合,使用递归思想进行操作会失败并且抛出异常。
这包括clone()、equals()、hashcode()和tostring()方法。
实现可以选择性地处理自引用场景,但是大多数当前实现类不这样做。

该接口是Java集合框架的一员。

对实现类的限制:

  • 对于默认方法(接口中使用default关键字标识的方法)不具有任何同步处理,子类如果需要进行同步处理,应该覆盖相应方法。

  • 所有子类行该拥有两种构造方法

因此我们知道,如果我们需要的定制一个新的集合类并实现Collecti接口,应该有两种构造器

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/132227.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!