zoukankan      html  css  js  c++  java
  • JDK源码阅读之Collection

    源码版本:JDK 1.7。

    集合 Collection,根据已知的内容可以知道有List、Set、Map(严格说,Map不属于Collection)等大类。

    先查看 Collection,

    public interface Collection<E> extends Iterable<E>

    JDK说明如下:

    /**
     * The root interface in the <i>collection hierarchy</i>.  A collection
     * represents a group of objects, known as its <i>elements</i>.  Some
     * collections allow duplicate elements and others do not.  Some are ordered
     * and others unordered.  The JDK does not provide any <i>direct</i>
     * implementations of this interface: it provides implementations of more
     * specific subinterfaces like <tt>Set</tt> and <tt>List</tt>.  This interface
     * is typically used to pass collections around and manipulate them where
     * maximum generality is desired.
     *
     * <p><i>Bags</i> or <i>multisets</i> (unordered collections that may contain
     * duplicate elements) should implement this interface directly.
     *
     * <p>All general-purpose <tt>Collection</tt> implementation classes (which
     * typically implement <tt>Collection</tt> indirectly through one of its
     * subinterfaces) should provide two "standard" constructors: a void (no
     * arguments) constructor, which creates an empty collection, and a
     * constructor with a single argument of type <tt>Collection</tt>, which
     * creates a new collection with the same elements as its argument.  In
     * effect, the latter constructor allows the user to copy any collection,
     * 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 <tt>Collection</tt>
     * implementations in the Java platform libraries comply.
     *
     * <p>The "destructive" methods contained in this interface, that is, the
     * methods that modify the collection on which they operate, are specified to
     * throw <tt>UnsupportedOperationException</tt> if this collection does not
     * support the operation.  If this is the case, these methods may, but are not
     * required to, throw an <tt>UnsupportedOperationException</tt> if the
     * invocation would have no effect on the collection.  For example, invoking
     * the {@link #addAll(Collection)} method on an unmodifiable collection may,
     * but is not required to, throw the exception if the collection to be added
     * is empty.
     *
     * <p><a name="optional-restrictions"/>
     * 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.  Attempting to
     * add an ineligible element throws an unchecked exception, typically
     * <tt>NullPointerException</tt> or <tt>ClassCastException</tt>.  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 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.
     *
     * <p>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.
     *
     * <p>Many methods in Collections Framework interfaces are defined in
     * terms of the {@link Object#equals(Object) equals} method.  For example,
     * the specification for the {@link #contains(Object) contains(Object o)}
     * method says: "returns <tt>true</tt> if and only if this collection
     * contains at least one element <tt>e</tt> such that
     * <tt>(o==null ? e==null : o.equals(e))</tt>."  This specification should
     * <i>not</i> be construed to imply that invoking <tt>Collection.contains</tt>
     * with a non-null argument <tt>o</tt> will cause <tt>o.equals(e)</tt> to be
     * invoked for any element <tt>e</tt>.  Implementations are free to implement
     * optimizations whereby the <tt>equals</tt> invocation is avoided, for
     * example, by first comparing the hash codes of the two elements.  (The
     * {@link Object#hashCode()} specification guarantees that two objects with
     * unequal hash codes cannot be equal.)  More generally, implementations of
     * the various Collections Framework interfaces are free to take advantage of
     * the specified behavior of underlying {@link Object} methods wherever the
     * implementor deems it appropriate.
     *
     * <p>This interface is a member of the
     * <a href="{@docRoot}/../technotes/guides/collections/index.html">
     * Java Collections Framework</a>.
     *
     * @param <E> the type of elements in this 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
     */

    大意是:

    Collection接口是集合框架的根接口。JDK没有为该接口提供任何直接实现,而是提供了更细化的子接口的实现,如Set、List。

    所有通用目的的实现类应该提供两个标准构造方法:一个空参数的构造器、一个单参数且参数类型为Collection的构造器。没有强制措施,纯属自觉,JDK很自觉。

    每个实现类的同步策略由自己决定。

    集合框架接口的很多方法都是基于equals方法,例如contains(obj)。

    不过,先不急于深入Collection接口,先看看其继承的Iterable接口,该接口只有一个方法:

    public interface Iterable<T> {
        Iterator<T> iterator();
    }

    继续展开 Iterator,还是一个接口:

    public interface Iterator<E> {
        boolean hasNext();
        E next();
        void remove();
    }

    如果使用过该接口,应该明白前两个方法的意义,一个用于判断是否还有下一个元素,另一个用于获取下一个元素同时移动游标。最后一个方法其实是删除当前指向的元素,属于可选的待实现接口方法。

    事实上,该接口,Iterator取代了原有的Enumeration接口,对比一下就明白了:

    public interface Enumeration<E> {
        boolean hasMoreElements();
        E nextElement();
    }

    Iterator 和 Enumeration 如出一辙,只不过 Iterator 更简洁,且多了一个操作。

    再返回来看看 Iterable 接口,其唯一的方法是 iterator(),要求返回一个 Iterator对象;所以 Collection 接口的实现们必然实现该方法,来测试一下:

    @Test
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public void testIterator() {
        Collection collection = null;
        collection = new ArrayList();
        collection.add(1);
        collection.add(2);
        collection.add(3);
    
        Iterator iterator = collection.iterator(); // Iterator
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

    OK,现在来看看Collection本身的接口:

    public interface Collection<E> extends Iterable<E> {
        // Query Operations  - 查询操作
        int size();
        boolean isEmpty();
        boolean contains(Object o);
        Iterator<E> iterator();
        Object[] toArray();
        <T> T[] toArray(T[] a);
    
        // Modification Operations  - 修改操作
        boolean add(E e);
        boolean remove(Object o);
    
    
        // Bulk Operations  - 批量操作
        boolean containsAll(Collection<?> c);
        boolean addAll(Collection<? extends E> c);
        boolean removeAll(Collection<?> c);
        boolean retainAll(Collection<?> c);
        void clear();
    
    
        // Comparison and hashing  - 对比和哈希
        boolean equals(Object o);
        int hashCode();
    }

    不明白为什么还有 iterator() 方法,冗余了吧。

    上面的方法,对我来说最需要了解的就是 toArray() 和 toArray(T[] a) :前者就是字面意思,将集合转成数组;后者虽然也是将集合转成数字,但是,会考虑集合的size和给定数组的length,如果给定数组能容纳集合的元素,则直接返回指定的数组(填充集合元素),否则,返回一个新创建的数组! -- 就是说,可能会省略分配内存这一步骤。

    来个示例:

    @Test
    public void testToArray() {
        // 定义集合
        Collection<String> collection = new ArrayList<>();
        for (int i = 0; i != 5; ++i) {
            collection.add(new String(new char[] { (char) ('a' + i) }));
            collection.add(null);
        }
        System.out.println(collection); //
    
        // 定义目标数组
        String[] t1 = new String[9];
        Arrays.fill(t1, "xxx");
        String[] t2 = new String[10];
        Arrays.fill(t2, "xxx");
        String[] t3 = new String[11];
        Arrays.fill(t3, "xxx");
        // 转换
        String[] r1 = collection.toArray(t1);
        String[] r2 = collection.toArray(t2);
        String[] r3 = collection.toArray(t3);
    
        // 看看返回的数组是否原有数组
        System.out.println(r1 == t1); // false
        System.out.println(r2 == t2); // true
        System.out.println(r3 == t3); // true
    
        System.out.println(Arrays.toString(r1));
        System.out.println(Arrays.toString(r2));
        System.out.println(Arrays.toString(r3)); // 注意,原数组如果仍有空余空间,全部null
    }

    >>>>>>>>>>>>>>>>>>>>>>>>>未完待续>>>>>>>>>>>>>>>>>>>>>>>>>

  • 相关阅读:
    软件工程期末考试复习(五)
    软件工程期末考试复习(四)
    软件工程期末考试复习(三)
    软件工程期末考试复习(二)
    shell脚本与mongo交互
    python使用单例模式创建MySQL链接
    python with上下文的浅谈
    Docker 基础概念科普 和 常用操作介绍
    MySQL聚集索引和非聚集索引
    为什么选择Python
  • 原文地址:https://www.cnblogs.com/larryzeal/p/6854123.html
Copyright © 2011-2022 走看看