JAVA集合一 ——集合結構



JAVA集合一 ——集合整體接口


     特別聲明:

     *本文只是備忘錄。

     JAVA中集合是一個很重要的概念,首先來看看整體的類圖。

    集合的主要接口爲collection。Collection 繼承自Iterable接口,而Iterable接口封裝了生成迭代器的方法Iterator()。這樣所有集合都需要實現該方法,這也是java設計模式中的迭代器模式。

      由圖中可以看出集合的幾個主要的子接口爲:List、Set、Queue。一個抽象實現類 AbstractCollection。

      List、Set、Queue接口後面分析。先來看AbstractCollection。

     AbstractCollection 主要是提供了一些Collection接口的方法的實現。

    主要看一下 toArray()方法。

 public Object[] toArray() {
        // Estimate size of array; be prepared to see more or fewer elements
        Object[] r = new Object[size()];
        Iterator<E> it = iterator();
        for (int i = 0; i < r.length; i++) {
            if (! it.hasNext()) // fewer elements than expected
                return Arrays.copyOf(r, i);
            r[i] = it.next();
        }
        return it.hasNext() ? finishToArray(r, it) : r;
    }

    將集合中的元素複製到數組中。看看最後返回的是什麼?最後爲什麼還要判斷it.hasNext()?

     能產生這種問題的情況,多線程!。

     在來看看 finishToArray()的源碼:

    

 private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
        int i = r.length;
        while (it.hasNext()) {
            int cap = r.length;
            if (i == cap) {
                int newCap = cap + (cap >> 1) + 1;
                // overflow-conscious code
                if (newCap - MAX_ARRAY_SIZE > 0)
                    newCap = hugeCapacity(cap + 1);
                r = Arrays.copyOf(r, newCap);
            }
            r[i++] = (T)it.next();
        }
        // trim if overallocated
        return (i == r.length) ? r : Arrays.copyOf(r, i);
    }
    第一步擴容
    擴容的算法,每次擴容原先容量的一半+1。
int newCap = cap + (cap >> 1) + 1;
    第二步
    如果擴容後的值大於集合定義的最大值,則表示數組太大,如果一次性擴容會佔用很多內存。需要重新擴容。通過傳入cap+1來生成一個合適的新值。
if (newCap - MAX_ARRAY_SIZE > 0)
                    newCap = hugeCapacity(cap + 1);
 
    private static int hugeCapacity(int minCapacity) {
        //該處判斷上面的cap + 1是否已經超出了int的最大值。
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError
                ("Required array size too large");
	//判斷擴容後的值是否大於數組的最大size,如果大於返回INT的最大值。否則返回定義的最大值
        return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE :MAX_ARRAY_SIZE;
    }
看看集合定義的最大值是多少:
   private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

     

      再來看看List、Set、Queue接口。

      List:定義的是有序的集合,允許元素的重複。允許多個null。

      Set:定義的是不能重複的集合,可以有null,但是只能有一個。Set分有序和無需的。TreeSet:有序,hashSet:無需。

      Queue: 定義的是"隊列"先進先出(FIFO)的數據結構。不允許隨機訪問。

      後面會具體分析。


發佈了13 篇原創文章 · 獲贊 10 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章