201621123061《Java程序設計》第八次學習總結

1. 本週學習總結

以你喜歡的方式(思惟導圖或其餘)概括總結集合相關內容。

2. 書面做業

1. ArrayList代碼分析

1.1 解釋ArrayList的contains源代碼

源代碼以下:javascript

public boolean contains(Object o) {
        return indexOf(o) >= 0; 
    }

public int indexOf(Object o) {              
        if (o == null) {                    
            for (int i = 0; i < size; i++)   
                if (elementData[i]==null)    
                    return i;                
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

ArrayList的contains方法調用了indexOf方法。indexOf方法是經過對ArrayList型的對象的遍歷,假如對象o找到和它相等的值,則放回該值的位置,不然返回-1。contains方法則是根據indexOf(o) >= 0是否成立來判斷,若成立則返回true,即包含,不成立返回false,即不包含。java

1.2 解釋E remove(int index)源代碼

源代碼以下:數組

public E remove(int index) {
    rangeCheck(index);          //檢查是否在範圍內

    modCount++;                    //初始值爲0
    E oldValue = elementData(index);     //保存舊數據

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);         //將移除位置以後全部的元素都向前挪動一個位置
    elementData[--size] = null;        //將最後一個元素置爲空
    return oldValue;                      
}
private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

首先判斷要刪除的位置是否超出的範圍:若是超出,則拋出異常,不然刪除該位置的元素,而且將移除位置以後全部的元素都向前挪動一個位置,將最後一個元素置爲空。函數

1.3 結合1.1與1.2,回答ArrayList存儲數據時須要考慮元素的具體類型嗎?

不須要。ArrayLis存儲是用Object[]數組實現的,Object是全部類的父類,因此不須要考慮元素的類型。學習

1.4 分析add源代碼,回答當內部數組容量不夠時,怎麼辦?

源代碼以下:this

public boolean add(E e) {
        ensureCapacityInternal(size + 1);            // 確保下一個元素進來有空間
        elementData[size++] = e;
        return true;
    }

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // DEFAULT_CAPACITY = 10,默認長度爲10
        }

        ensureExplicitCapacity(minCapacity);
    }

    private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);                       
    }

private void grow(int minCapacity) {                         //增長容量
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);  //增長原來容量的一半。
        if (newCapacity - minCapacity < 0)             //判斷容量是否足夠,夠的話就直接以這個長度建立數組
            newCapacity = minCapacity;                       
        if (newCapacity - MAX_ARRAY_SIZE > 0)                //若是不夠,再擴充
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);//最後將原來的複製到新的數組中  
    }

private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;                                   //MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8
    }

1.5 分析private void rangeCheck(int index)源代碼,爲何該方法應該聲明爲private而不聲明爲public?

源代碼以下:code

private void rangeCheck(int index) {
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

rangeCheck方法用來判斷是否超出容量範圍,沒有返回值,假如超出範圍了就直接拋出異常。使用private是由於用戶不須要知道rangeCheck方法是如何操做,由於在進行各個方法的調用時須要該方法時就會自動被調用,開發者不須要本身手動進行判斷是否越界。對象

2. HashSet原理

2.1 將元素加入HashSet(散列集)中,其存儲位置如何肯定?須要調用那些方法?

首先要調用hashCode方法獲得相應的哈希值,而後對哈希值進行計算,算出在哈希表中對應的位置。若是對應的位置上沒有值,則將元素放在該位置上,若是該位置上有別的值,則調用equals方法比較位置上的值和要加入的元素的值,若是爲true,則說明兩個值相等,而HashSet不容許有重複的值,則用新元素代替就元素,若是結果爲false,就經過散列衝突的解決辦法解決。blog

2.2 將元素加入HashSet中的時間複雜度是多少?是O(n)嗎?(n爲HashSet中已有元素個數)

將元素加入HashSet中不須要遍歷,時間複雜度爲O(1)。排序

2.3 選作:嘗試分析HashSet源代碼後,從新解釋2.1

源代碼以下:

public boolean contains(Object o) {
    return map.containsKey(o);
}

public boolean containsKey(Object key) {    //若是此映射包含對於指定鍵(key)的映射關係,則返回true

    return getEntry(key) != null;  
} 
final Entry<K,V> getEntry(Object key) { //經過key獲取value
    int hash = (key == null) ? 0 : hash(key.hashCode());//
    for (Entry<K,V> e = table[indexFor(hash, table.length)]; e != null; e = e.next) { 
        Object k;    
        if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k))))  
            return e;  
    }
    return null; 
}

調用contains方法,contains又調用map.containsKey方法,該方法又調用getEntry方法來獲取value。containsKey對返回的Keyvalue判斷,若是爲空在返回false,不然返回true。

3. ArrayListIntegerStack

題集jmu-Java-05-集合之ArrayListIntegerStack

3.1 比較本身寫的ArrayListIntegerStack與本身在題集jmu-Java-04-面向對象2-進階-多態、接口與內部類中的題目自定義接口ArrayIntegerStack,有什麼不一樣?(不要出現大段代碼)

  • ArrayListIntegerStack利用ArrayList實現棧的存儲,ArrayList是長度可變化的數組,沒必要考慮棧滿的狀況。
  • ArrayIntegerStack利用長度不可變數組來實現棧的存儲,說數組不可變,實際上是由於一開始就要設定好數組的長度,須要考慮棧滿的狀況。

    3.2 結合該題簡單描述接口的好處,需以3.1爲例詳細說明,不可泛泛而談。

    接口對類的全部共性方法進行聲明,實現這個接口的類再對方法進行重寫。在3.1中,ArrayListIntegerStack和ArrayIntegerStack都有共同的方法,可是對這些方法的實現,對棧的存儲方式不同(重寫的方法又不同)。接口的方法在不一樣的類中實現,實現起來又能有不同的功能,這樣會比較方便,彌補了類不能被多繼承的缺憾。

4. Stack and Queue

4.1 編寫函數判斷一個給定字符串是不是迴文,必定要使用棧(請利用Java集合中已有的類),但不能使用java的Stack類(具體緣由本身搜索)與數組。請粘貼你的代碼,類名爲Main你的學號。

4.2 題集jmu-Java-05-集合之銀行業務隊列簡單模擬(只粘貼關鍵代碼)。請務必使用Queue接口,並說明你使用了Queue接口的哪個實現類?


使用了Queue接口的實現類Deque。

5. 統計文字中的單詞數量並按單詞的字母順序排序後輸出

題集jmu-Java-05-集合之5-2 統計文字中的單詞數量並按單詞的字母順序排序後輸出 (做業中不要出現大段代碼)

5.1 實驗總結


這題關鍵是要用TreeSet,能夠自動排序。

3.碼雲及PTA

題目集:jmu-Java-05-集合

3.1. 碼雲代碼提交記錄

在碼雲的項目中,依次選擇「統計-Commits歷史-設置時間段」, 而後搜索並截圖

3.2 截圖PTA題集完成狀況圖

須要有兩張圖(1. 排名圖。2.PTA提交列表圖)

3.3 統計本週完成的代碼量

須要將每週的代碼統計狀況融合到一張表中。

周次 行數 新增行數 文件數 新增文件數
1 91 91 5 5
2 504 413 18 13
3 1092 588 28 10
5 1158 129 34 6
6 1539 381 40 6
7 2023 484 49 9
8 2477 454 57 8
9 2709 232 63 6
相關文章
相關標籤/搜索