1. 本週學習總結

以你喜歡的方式(思維導圖或其他)歸納總結集合相關內容。

參考資料:

XMind

答:

大多數情況下,從效能上來說ArrayList最好,但是當集合內的元素需要頻繁插入、刪除時LinkedList會有比較好的表現,但是它們三個效能都比不上陣列,另外Vector是執行緒同步的。所以:

如果能用陣列的時候(元素型別固定,陣列長度固定),請儘量使用陣列來代替List;

如果沒有頻繁的刪除插入操作,又不用考慮多執行緒問題,優先選擇ArrayList;

如果在多執行緒條件下使用,可以考慮Vector;

如果需要頻繁地刪除插入,LinkedList就有了用武之地;

2. 書面作業

ArrayList程式碼分析

1.1 解釋ArrayList的contains原始碼

答:

原始碼:

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;
}

先執行indexOf(),判斷Object o是否在elementData中存在,如果存在則返回序號,不存在就返回-1,再判斷返回值是否大於等於0;若大於則返回true,即,如果Object o在elementData中存在就返回true。

1.2 解釋E remove(int index)原始碼

答:

原始碼:

    public E remove(int index) {
rangeCheck(index); modCount++;
E oldValue = elementData(index); int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work return oldValue;
} private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

首先,判斷輸入的index是否超過了size,如果超過則發生IndexOutOfBoundsException異常,然後,刪除指定位置的元素,再把後面所有元素向前移動一位,最後一位的值變成null。

1.3 結合1.1與1.2,回答ArrayList儲存資料時需要考慮元素的型別嗎?

答:不用考慮,ArrayList儲存資料時除了基本資料型別,其他所有型別都可以存放,可以有相同的元素,也可以有null元素。

1.4 分析add原始碼,回答當內部陣列容量不夠時,怎麼辦?

答:

public boolean add(E e) {
ensureCapacityInternal(size + 1); // 首先要確保容量是size+1,保證所有元素能裝進去
elementData[size++] = e;
return true;
} private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);//確保陣列容量是傳入引數和預設長度的最大值
} private void ensureExplicitCapacity(int minCapacity) { modCount++;// 將modCount增加一位 if (minCapacity - elementData.length > 0)//如果需要的容量比現有陣列長度大,則呼叫grow方法增加容量
grow(minCapacity);
} private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); //容量變為原來的1.5倍
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);
}

1.5 分析private void rangeCheck(int index)原始碼,為什麼該方法應該宣告為private而不宣告為public?

答:

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

因為外部不需要知道這個方法的具體操作過程,也不讓外部知道,外部只需要知道方法執行的結果就好。

HashSet原理

2.1 將元素加入HashSet(雜湊集)中,其儲存位置如何確定?需要呼叫那些方法?

答:當我們向HashSet中新增一個元素時,HashSet會先呼叫該物件的hashCode()方法得到其hashCode值,根據該值決定該物件在桶中儲存位置,如果桶中已有其他元素,則呼叫加入物件的equals()方法與已有元素進行比較。如果比較結果為假,則將物件插入桶中。如果比較結果為真,則用新的值替換舊的值。

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

3.1 比較自己寫的ArrayListIntegerStack與自己在題集jmu-Java-04-面向物件2-進階-多型、介面與內部類中的題目5-3自定義介面ArrayIntegerStack,有什麼不同?(不要出現大段程式碼)

答:ArrayListIntegerStack用ArrayList來實現棧,ArrayIntegerStack用Integer陣列來實現棧,是內部實現陣列與動態陣列的區別,ArrayList不需要考慮陣列長度,可以自動擴容,而Integer會受陣列長度的約束。

3.2 簡單描述介面的好處.

答:例如本題,兩個類都繼承了同一個介面,但方法的實現是不一樣的,可以在介面中定義多個抽象方法,也就是說我們可以通過不同的路徑達到同樣的目的,提高工作效率。

Stack and Queue

4.1 編寫函式判斷一個給定字串是否是迴文,一定要使用棧,但不能使用java的Stack類(具體原因自己搜尋)。請貼上你的程式碼,類名為Main你的學號。

答:

public class Main201521123001 {
public static void main(String[] args) {
Stack<Character> stack = new Stack<Character>();
String str = "121";
//String str = "123";
for(int i = 0; i < str.length(); i++){
stack.push(str.charAt(i));
}
boolean flag = true;
for(int i = 0; i < str.length(); i++){
if(stack.pop() != str.charAt(i)){
flag = false;
break;
}
}
if (flag) {
System.out.println("yes");
} else {
System.out.println("no");
}
}
} class Stack<E>{
private LinkedList<E> stack = new LinkedList<E>();
public void push(E o){
stack.addFirst(o);
}
public E peek(){
return stack.getFirst();
}
public E pop(){
return stack.removeFirst();
}
public boolean empty(){
return stack.isEmpty();
}
public String toString(){
return stack.toString();
}
}

4.2 題集jmu-Java-05-集合之5-6 銀行業務佇列簡單模擬。(不要出現大段程式碼)

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


答:首先定義兩個視窗A、B,根據奇偶分別入隊,當兩隊不為空時,A出兩次隊,B出一次,再將非空隊內元素全部輸出。

while(!A.isEmpty() && !B.isEmpty()){
dosth();
System.out.print(A.poll());
if(!A.isEmpty()){
dosth();
System.out.print(A.poll());
}
dosth();
System.out.print(B.poll());
}

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

5.1 實驗總結

答:while迴圈讀入輸入的字串,用+將後一行與先前輸入的字串相連,判斷輸入若為“!!!!!”則跳出迴圈,使用TreeSet儲存會自動按字母順序排列,因此只要按序輸出就好。

面向物件設計大作業-改進

7.1 完善圖形介面(說明與上次作業相比增加與修改了些什麼)

答:

7.2 使用集合類改進大作業

參考資料:

JTable參考專案

未完成

3. 碼雲上程式碼提交記錄及PTA實驗總結

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

3.1. 碼雲程式碼提交記錄

在碼雲的專案中,依次選擇“統計-Commits歷史-設定時間段”, 然後搜尋並截圖

答:

3.2. PTA實驗

程式設計(5-1, 5-2, 5-3(選做), 5-6)

實驗總結已經在作業中體現,不用寫。