Collection 接口

十年热恋 提交于 2020-04-06 03:57:09

        Collection 是java 集合层次结构的根接口,包含了List 和 Set 的所有通用方法并且给出了说明,了解一下有助于理解具体集合实现类的相关方法的实现细节。在此先列出jdk1.8 之前的方法:

/**
 * 集合层次结构中的根接口。集合表示一组对象,这些对象在集合中称为“元素”
 * 一些集合允许重复的元素,而另一些则不允许。 一些是有序的,而其他则是无序的。
 * JDK没有提供此接口的任何直接实现:它提供了更具体的子接口的实现,例如Set 和 List。
 * 该接口通常用于传递集合并在需要最大通用性的地方操作它们。
 */
public interface Collection<E> extends Iterable<E> {// Iterable<E>是迭代器接口
    // Query Operations 查询操作

    /**
     * 返回此集合中的元素个数。
     * 如果大于 Integer.MAX_VALUE 就返回 Integer.MAX_VALUE
     */
    int size();

    /**
     * 如果此集合不包含任何元素就返回 true
     */
    boolean isEmpty();

    /**
     * 如果此集合包含指定的元素就返回 true
     * 通常,当且仅当至少包含一个元素 e 满足 (o==null ? e==null: o.equals(e)) 返回 true
     * @throws ClassCastException 如果指定元素的类型与此集合不兼容就抛出此异常
     * @throws NullPointerException 如果指定的元素是 null且此集合不允许有 null 就抛出此异常
     */
    boolean contains(Object o);

    /**
     * 返回对此集合中的元素进行迭代的迭代器。 
     * 没有关于元素返回顺序的保证(除非此集合是某个提供保证的类的实例)。
     */
    Iterator<E> iterator();

    /**
     * 返回一个包含此集合中所有元素的数组。 
     * 如果此集合保证其迭代器返回其元素的顺序,则此方法必须以相同的顺序返回元素。
     * <p>返回的数组将是“安全的”,因为此集合不维护对其的引用。
     * 换句话说,即使此集合由数组支持,此方法也必须分配一个新数组。因此,调用方可以自由修改返回的数组。
     * <p>此方法充当基于数组的API和基于集合的API之间的桥梁。
     */
    Object[] toArray();

    /**
     * 返回包含此集合中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。
     * 如果集合适合指定的数组,则将其返回。 
     * 否则,将使用指定数组的运行时类型和此集合的大小分配一个新数组。
     *
     * <p>如果此集合适合指定的数组并有剩余空间(即,数组比该集合具有更多的元素),
     * 则紧接集合结束后的数组中的元素将设置为 null 。 
     * 如果调用者知道此集合不包含任何 null元素,则此方法仅在确定此集合的长度时很有用。​​​​
     * <p>如果此集合保证其迭代器返回其元素的顺序,则此方法必须以相同的顺序返回元素。
     *
     * <p>此方法充当基于数组的API和基于集合的API之间的桥梁。 
     * 此外,此方法允许对输出数组的运行时类型进行精确控制,并且在某些情况下可以用于节省分配成本。
     * <p>假设 x 是一个仅包含字符串的集合,以下代码可用于将集合转储到新分配的 String 数组中:
     * <pre>
     *     String[] y = x.toArray(new String[0]);</pre>
     * 请注意,toArray(new Object [0])在功能上与 toArray() 相同。
     *
     * @param <T> 包含集合的数组的运行时类型
     * @param 一个数组,如果足够大,此集合的元素将存储在该数组中;否则,将为此分配一个具有相同运行时类型的新数组。
     * @return 包含此集合中所有元素的数组
     * @throws ArrayStoreException 如果指定数组的运行时类型不是此集合中每个元素的运行时类型的超类型,就抛出此异常
     * @throws NullPointerException 如果指定的数组为 null,就抛出此异常
     */
    <T> T[] toArray(T[] a);

    // Modification Operations 修改操作

    /**
     * 确保此集合包含指定的元素(可选操作)。
     * 如果此集合由于调用而更改,则返回 true 。如果此集合不允许重复并且已经包含指定的元素,则返回 false 。
     *
     * 支持此操作的集合可能会对可以添加到此集合的元素施加限制。
     * 特别是某些集合将拒绝添加 null元素,而其他集合将对可能添加的元素的类型施加限制。
     * 集合类应在其文档中明确指定对可以添加的元素的任何限制
     *
     * 如果某个集合以除已包含该元素以外的其他任何原因拒绝添加某个特定元素,则它必须引发异常(而不是返回 false )
     *  这保留了不变,即在此调用返回之后,集合始终包含指定的元素。
     *
     * @param e 要确保其存在于此集合中的元素
     * @return  如果该集合因调用而改变返回 true
     * @throws UnsupportedOperationException 如果此集合不支持该操作,就抛出此异常(因为是可选操作
     * @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 如果由于此调用而删除了元素,返回 true
     * @throws ClassCastException 如果指定元素的类型与此集合不兼容,就抛出此异常
     * @throws NullPointerException 如果指定的元素为null,并且此集合不允许使用null元素,就抛出此异常
     * @throws UnsupportedOperationException 如果此集合不支持该操作,就抛出此异常(因为是可选操作)
     */
    boolean remove(Object o);


    // Bulk Operations 批量操作

    /**
     * 如果此集合包含指定集合中的所有元素,就返回 true
     *
     * @param  c 要检查是否包含在此集合中的集合
     * @return
     * @throws ClassCastException 如果指定集合中一个或多个元素的类型与此集合不兼容,就抛出此异常
     * @throws NullPointerException 如果指定的集合包含一个或多个null元素,
     *         并且此集合不允许null元素或者指定集合是null,就抛出此异常
     * @see    #contains(Object)
     */
    boolean containsAll(Collection<?> c);

    /**
     * 将指定集合中的所有元素添加到此集合中(可选操作)。
     * 如果在该操作进行过程中修改了指定的集合,则此操作的行为是不确定的。
     * 这意味着如果指定的集合是此集合,并且此集合是非空的,则此调用的行为是不确定的。
     *
     * @param c 包含要添加到此集合中的元素的集合
     * @return 如果该集合是因此调用而改变,就返回 true
     * @throws UnsupportedOperationException 如果此集合不支持该操作,就抛出此异常(因为是可选操作)
     * @throws ClassCastException 如果指定集合的元素的类阻止将其添加到此集合中,就抛出此异常
     * @throws NullPointerException 如果指定的集合包含null元素,并且此集合不允许使用null元素,
     *         或者指定的collection为null,就抛出此异常
     * @throws IllegalArgumentException 如果指定集合的元素的某些属性阻止将其添加到此集合,就抛出此异常
     * @throws IllegalStateException 如果由于插入限制,此时无法添加所有元素,就抛出此异常
     * @see #add(Object)
     */
    boolean addAll(Collection<? extends E> c);

    /**
     * 删除指定集合中也包含的所有此集合元素(可选操作
     *
     * @param c 包含要从此集合中删除的元素的集合
     * @return 如果该集合是因此调用而改变,就返回 true
     * @throws UnsupportedOperationException 如果此集合不支持该操作,就抛出此异常(因为是可选操作)
     * @throws ClassCastException 如果此集合中一个或多个元素的类型与指定的集合不兼容,就抛出此异常
     * @throws NullPointerException 如果此集合包含一个或多个null元素,并且指定的集合不支持null元素,
     *         或者指定的集合为null,就抛出此异常
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean removeAll(Collection<?> c);

    /**
     * 仅保留此集合中包含在指定集合中的元素(可选操作)。
     * 换句话说,从此集合中删除所有未包含在指定集合中的元素。
     * @param c 包含要保留在此集合中的元素的集合
     * @return 如果该集合是因此调用而改变,就返回 true
     * @throws UnsupportedOperationException 如果此集合不支持该操作,就抛出此异常(因为是可选操作)
     * @throws ClassCastException 如果此集合中一个或多个元素的类型与指定的集合不兼容,就抛出此异常
     * @throws NullPointerException 如果此集合包含一个或多个null元素,并且指定的集合不支持null元素,
     *         或者指定的集合为null,就抛出此异常
     * @see #remove(Object)
     * @see #contains(Object)
     */
    boolean retainAll(Collection<?> c);

    /**
     * 从此集合中删除所有元素(可选操作)。
     * 此方法返回后,集合将为空。
     * @throws UnsupportedOperationException 如果此集合不支持该操作,就抛出此异常(因为是可选操作)
     */
    void clear();


    // Comparison and hashing  比较和哈希
 
    /**
     * 比较指定对象与此集合的相等性。
     *
     * 尽管 Collection 接口没有为 Object.equals 常规约定添加任何限制,但是直接实现
     * Collection(换而言之,创建一个集合类但不是 List 或者 Set)的程序员,如果选择
     * 覆盖 equals 方法就必须注意。
     * 其实不必这样做,最简单的方法就是依靠 Object 的实现,
     * 但是实现者可能希望实现“值比较”来代替默认的“引用比较”。
     * (List 和 Set 接口就要求这种 “值比较”)
     * 
     * Object.equals 方法的常规约定规定,equals必须是对称的(换句话说,当且仅当 b.equals(a) 等价 a.equals(b))
     * List.equals 和 Set.equals 的约定规定,列表仅等于其他列表,集合仅等于其他集合。
     * 因此,对于既不实现 List 也不实现 Set 接口的集合类的自定义 equals 方法,在以下情况下必须返回 false: 
     * 将此集合与任何列表或集合进行比较。(按照此逻辑,不可能编写一个可以正确实现 Set 和 List 接口的类。)
     *
     * @param o 要与此对象进行相等性比较的对象
     * @return 如果指定的对象等于此集合,就返回 true
     *
     * @see Object#equals(Object)
     * @see Set#equals(Object)
     * @see List#equals(Object)
     */
    boolean equals(Object o);

    /**
     * 返回此集合的哈希码值。
     * 尽管 Collection 接口没有为 Object.hashCode 方法的常规约定添加任何规定,
     * 但程序员应注意,任何覆盖 Object.equals 的类还必须重写 Object.hashCode 方法,
     * 以便满足 Object.hashCode 方法的常规约定
     * 特别是 c1.equals(c2) 意味着 c1.hashCode() == c2.hashCode()。
     *
     * @return 此集合的哈希码值
     *
     * @see Object#hashCode()
     * @see Object#equals(Object)
     */
    int hashCode();

        看完发现没有随机访问所选择元素的get() 方法。因为Collection 包括 Set ,而Set 是自己维护内部顺序的(这使得随机访问变得没有意义)。因此,如果想检查 Collection 中的元素,那就必须使用迭代器。

可选操作

        在方法注释中有几个方法被标注为:可选操作。执行各种不同的添加和移除的方法在Collection 接口中都是可选操作,这意味着实现类并不需要为这些方法提供功能定义。为什么要这样做呢?因为这样做可以防止在设计中出现接口爆炸的情况。“未获支持的操作”这种方式可以实现Java 容器类库的一个重要目标:容器应该易学易用。未

        获支持的操作是一种特例,可以延迟到需要时在实现。目前几乎所有容器类都会支持所有的操作。这种设计留下了一个“后门”,程序员需要创建新的集合类,但是没有为Collection 接口中的所有方法都提供有意义的定义,它仍旧适合现有的类库。如果一个操作是未获支持的,在实现接口的时候可能就会导致抛出未获支持异常,而不是等到产品交后出现此异常。

        最常见的未获支持的操作,都来源于背后由固定尺寸的数据结构支持的容器。Arrays.asList()(数组转列表) 将数组转换为List 时,就会得到这样的容器。

        还有一个方法:Collections.unmodifiableList() 产生不可修改的列表。Collections 类中的“不可修改” 的方法将容器包装到了一个代理中,只要你执行任何试图修改容器的操作,这个代理都会产生 UnsupportedOperationException 异常。使用这些方法的目标就是产生 “常量” 容器对象。

 

 

 

 

 

参考资料:

        《Java 编程思想》

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!