Android基礎之Java集合框架Collection

silencezwm發表於2019-03-04


一、Collection是什麼

JavaCollection.png

首先我們一起來探討一下Collection究竟是什麼個玩意,如上圖所示List、Set、Queue、Map都指向Collection,它們都只是一個介面,並不是實現類。正因為有了Collection集合框架,使我們能方便的批量運算元據或物件。

二、List
List是有序的Collection,我們可以非常輕鬆的來控制資料插入的位置,並且也能根據其索引來訪問List中的某個元素。
其實List實現類還是挺多的【AbstractList, AbstractSequentialList, ArrayList, CopyOnWriteArrayList, LinkedList, Stack, Vector】,但今天我們主要來講講常用的類ArrayList、LinkedList、Vector。

2.1 ArrayList
看名稱就知道Arraylist是基於陣列的連結串列,且執行緒不同步。我們可以看下其實現的add方法原始碼:

@Override 
public boolean add(E object) {
    Object[] a = array;
    int s = size;
    if (s == a.length) {
        Object[] newArray = new Object[s +
            (s < (MIN_CAPACITY_INCREMENT / 2) ?
             MIN_CAPACITY_INCREMENT : s >> 1)];
        System.arraycopy(a, 0, newArray, 0, s);
        array = a = newArray;
    }
    a[s] = object;
    size = s + 1;
    modCount++;
    return true;
  }
複製程式碼

2.2 Vector
Vector也是基於陣列的連結串列,但是其執行緒是同步的【如下add方法被synchronized修飾】,其實現的add方法原始碼:

@Override
public synchronized boolean add(E object) {
    if (elementCount == elementData.length) {
        growByOne();
    }
    elementData[elementCount++] = object;
    modCount++;
    return true;
}
複製程式碼

效能方面:Vector比Arraylist和Array都低;
執行緒方面:Vector執行緒同步,ArrayList執行緒不同步;

2.3 LinkedList
LinkedList與Vector、ArrayList有著明顯的區別,其並不基於陣列,所以對LinkedList元素進行增加、刪除時,不需要批量移動其他元素。
其每個節點都包含以下兩個資訊:
1、該節點的資料
2、下一個節點的資訊

小總結:基於Array的List(Vector、ArrayList)適合查詢,LinkedList適合增刪操作。

三、Set
Set是不包含重複的元素的無序Collection,並且Set都是基於Map實現的。
如果使用add()方法存入已存在的元素,則會覆蓋之前的元素。
基於Set實現的類有AbstractSet, CopyOnWriteArraySet, EnumSet, HashSet, LinkedHashSet, TreeSet。

3.1 HashSet
我們可以先看下HashSet中的add()方法的原始碼:

transient HashMap<E, HashSet<E>> backingMap;


@Override
public boolean add(E object) {
    return backingMap.put(object, this) == null;
}
複製程式碼

其中backingMap為HashMap物件,我們應該知道HashMap是以鍵值對的形式來儲存資料的,而在上述add()方法中,鍵為傳入的物件,所以這就是Set不包含重複元素的最根本原因。

3.2 TreeSet
TreeSet是SortedSet的子類,它與HashSet最根本的區別在於:TreeSet是有序的,因為TreeSet是基於SortedMap來實現的。

四、Map
我們在聊Set的時候說道了HashMap,所以Map始終是以鍵值對形式存在的,並且其中的鍵是不允許重複的。
Map的常見實現有:HashMap和TreeMap。
如果我們要往HashMap中存入資料就可以使用put(Object key,Object value)方法,如果要取出資料也特別簡單,使用get(Object key)方法。
在這裡,我主要想聊聊HashMap和HashTable兩個類的區別:

一、HashTable類是基於抽象類Dictionary的,而HashMap類是基於Map介面的實現;
二、HashTable類是同步的,這就保證了執行緒的安全,HashMap類是不同步的;
三、HashTable類元素不能為空,否則系統會拋空指標異常,而HashMap類value是可以為空的,當然啦,其中key也是可以為空的,但是如果我們這樣設定,似乎毫無意義。
複製程式碼

五、Queue
Queue(佇列)先進先出,Stack(棧)後進先出。
方法名 方法含義 備註
add 增加一個元索 如果佇列已滿,則丟擲一個IIIegaISlabEepeplian異常
remove 移除並返回佇列頭部的元素 如果佇列為空,則丟擲一個NoSuchElementException異常
element 返回佇列頭部的元素 如果佇列為空,則丟擲一個NoSuchElementException異常
offer 新增一個元素並返回true 如果佇列已滿,則返回false
poll 移除並返問佇列頭部的元素 如果佇列為空,則返回null
peek 返回佇列頭部的元素 如果佇列為空,則返回null
put 新增一個元素 如果佇列滿,則阻塞
take 移除並返回佇列頭部的元素 如果佇列為空,則阻塞



相關文章