java經常使用集合類對比

簡介

Java中集合類有不少,只介紹經常使用的集合類:html

     

 線程安全和非線程安全的集合對象

1、概念:java

  • 線程安全:就是當多線程訪問時,採用了加鎖的機制;即當一個線程訪問該類的某個數據時,會對這個數據進行保護,其餘線程不能對其訪問,直到該線程讀取完以後,其餘線程纔可使用。防止出現數據不一致或者數據被污染的狀況。
  • 線程不安全:就是不提供數據訪問時的數據保護,多個線程可以同時操做某個數據,從而出現數據不一致或者數據污染的狀況。
  • 對於線程不安全的問題,通常會使用synchronized關鍵字加鎖同步控制。
  • 線程安全工做原理:jvm中有一個main memory對象,每個線程也有本身的working memory,一個線程對於一個變量variable進行操做的時候, 都須要在本身的working memory裏建立一個copy,操做完以後再寫入main memory。 當多個線程操做同一個變量variable,就可能出現不可預知的結果。
    而用synchronized的關鍵是創建一個監控monitor,這個monitor能夠是要修改的變量,也能夠是其餘本身認爲合適的對象(方法),而後經過給這個monitor加鎖來實現線程安全,每一個線程在得到這個鎖以後,要執行完加載load到working memory 到 use && 指派assign 到 存儲store 再到 main memory的過程。纔會釋放它獲得的鎖。這樣就實現了所謂的線程安全。

2、線程安全(Thread-safe)的集合對象:算法

  • Vector 線程安全:
  • HashTable 線程安全:
  • StringBuffer 線程安全:

3、非線程安全的集合對象:api

  • ArrayList :
  • LinkedList:
  • HashMap:
  • HashSet:
  • TreeMap:
  • TreeSet:
  • StringBulider:

4、相關集合對象比較:數組

Vector、ArrayList、LinkedList:
一、Vector:
     Vector與ArrayList同樣,也是經過數組實現的,不一樣的是它支持線程的同步,即某一時刻只有一個線程可以寫Vector,避免多線程同時寫而引發的不一致性,但實現同步須要很高的花費,所以,訪問它比訪問ArrayList慢。
二、ArrayList:
  a. 當操做是在一列數據的後面添加數據而不是在前面或者中間,並須要隨機地訪問其中的元素時,使用ArrayList性能比較好。
  b. ArrayList是最經常使用的List實現類,內部是經過數組實現的,它容許對元素進行快速隨機訪問。數組的缺點是每一個元素之間不能有間隔,當數組大小不知足時須要增長存儲能力,就要講已經有數組的數據複製到新的存儲空間中。當從ArrayList的中間位置插入或者刪除元素時,須要對數組進行復制、移動、代價比較高。所以,它適合隨機查找和遍歷,不適合插入和刪除。
三、LinkedList:
  a. 當對一列數據的前面或者中間執行添加或者刪除操做時,而且按照順序訪問其中的元素時,要使用LinkedList。
  b. LinkedList是用鏈表結構存儲數據的,很適合數據的動態插入和刪除,隨機訪問和遍歷速度比較慢。另外,他還提供了List接口中沒有定義的方法,專門用於操做表頭和表尾元素,能夠看成堆棧、隊列和雙向隊列使用。安全

Vector和ArrayList在使用上很是類似,均可以用來表示一組數量可變的對象應用的集合,而且能夠隨機的訪問其中的元素。數據結構

ArryList和LinkedList的區別:多線程

Vector與ArrayList比較:jvm

 1. 性能上ide


ArrayList底層數據結構是數組,適合隨機查找和遍歷,不適合插入和刪除,線程不安全,效率高。。LinkedList底層數據結構是鏈表, 適合數據的動態插入和刪除,隨機訪問和遍歷速度比較慢,線程不安全,效率高。。

 2. 同步性

    Vectors是可同步的,是線程安全的。ArrayList是不可同步的,不是線程安全的。因此,通常單線程推薦用ArrayList,多線程中則用Vector 

 3. 數據增加

    往一個ArrayList或者Vector裏插入一個元素時,若是內部數組空間不夠,ArrayList或Vector會擴展它的大小。Vector在默認狀況下增加一倍的大小,而ArrayList增長50%的大小。

HashTable、HashMap、HashSet:
     HashTable和HashMap採用的存儲機制是同樣的,不一樣的是:
一、HashMap:
a. 採用數組方式存儲key-value構成的Entry對象,無容量限制;
b. 基於key hash查找Entry對象存放到數組的位置,對於hash衝突採用鏈表的方式去解決;
c. 在插入元素時,可能會擴大數組的容量,在擴大容量時需要從新計算hash,並複製對象到新的數組中;
d. 是非線程安全的;
e. 遍歷使用的是Iterator迭代器;

二、HashTable:
a. 是線程安全的;
b. 不管是key仍是value都不容許有null值的存在;在HashTable中調用Put方法時,若是key爲null,直接拋出NullPointerException異常;
c. 遍歷使用的是Enumeration列舉;

三、HashSet:
a. 基於HashMap實現,無容量限制;
b. 是非線程安全的;
c.不保證數據的有序

TreeSet、TreeMap:
    TreeSet和TreeMap都是徹底基於Map來實現的,而且都不支持get(index)來獲取指定位置的元素,須要遍從來獲取。另外,TreeSet還提供了一些排序方面的支持,例如傳入Comparator實現、descendingSet以及descendingIterator等。
一、TreeSet:
a. 基於TreeMap實現的,支持排序;
b. 是非線程安全的;

二、TreeMap:
a. 典型的基於紅黑樹的Map實現,所以它要求必定要有key比較的方法,要麼傳入Comparator比較器實現,要麼key對象實現Comparator接口;
b. 是非線程安全的;

Collection有兩個子接口:List和Set,兩者主要區別在於:list數據有序存放、可重複;set中數據無序存放,不可重複。

Vector

  Vector類實現了一個動態數組,主要用在事先不知道數組的大小,以及須要頻繁地進行查找,插入,刪除工做,或者只是須要一個能夠改變大小的數組的狀況。

建立:

Vector類支持4種構造方法。

第一種構造方法建立一個默認的向量,默認大小爲10:

Vector()

第二種構造方法建立指定大小的向量。

Vector(int size)

第三種構造方法建立指定大小的向量,而且增量用incr指定. 增量表示向量每次增長的元素數目(當該vector對象添加的元素接近原先分配的內存極限時,會以incr大小自動擴大該對象擁有的內存容量,以容納更多的數據)

Vector(int size,int incr)

第四中構造方法建立一個包含集合c元素的向量:利用父類對象建立子類對象

Vector(Collection c)

  經常使用的vector操做方法:增、刪、查、改。

增:

vec.add(E element) 
將指定元素追加到此向量的末尾。 
vec.add(int index, E element) 
在此向量的指定位置插入指定的元素。 
vec.addAll(Collection c) 
將指定 Collection 中的全部元素按順序追加到此向量的末尾。 
vec.addAll(int index, Collection c) 
在指定位置將指定 Collection 中的全部元素插入到此向量中。

刪:

vec.remove(int index) 
移除此向量中指定位置的元素。 
vec.remove(value v) 
移除向量中元素值爲v的元素。
vec.removeAll(Collection c) 
今後向量中移除包含在集合c 中的全部元素。 
vec.removeAllElements() 
今後向量中移除所有組件,並將其大小設置爲零。 
vec.removeRange(int fromIndex, int toIndex) 
移除位於 fromIndex(包括)與 toIndex(不包括)之間的全部元素。

vec.clear() 移除全部元素。

查:

vec.get(int index)

返回向量中指定位置的元素。 
vex.indexOf(value v) 
返回v值在vec中的下標。
vec.isEmpty() 
檢查該向量是否爲空。 
vec.lastElement() 
返回此向量的最後一個元素。

int capacity() 
返回此向量的當前容量。

int size() 
返回此向量中的組件數。

String toString() 
返回此向量的字符串表示形式,其中包含每一個元素的 String 表示形式。 
改:

vec.set(int index, E element) 
用指定的元素替換此向量中指定位置處的元素。 
vex.setElementAt(E obj, int index) 
將此向量指定 index 處的組件設置爲指定的對象。 
vec.setSize(int newSize) 
設置此向量的大小。

ArrayList

ArrayList就是動態的數組,能夠動態的增長和減小元素,靈活的設置數組的大小。基本與Vector同樣。

建立:

 ArrayList提供了三個構造器:

public ArrayList(); 
默認的構造器,將會以默認(16)的大小來初始化內部的數組 
public ArrayList(Collection c); 
用一個集合對象來構造,並將該集合的元素添加到ArrayList 
public ArrayList(int n); 
用指定n的大小來初始化內部的數組.

增:

方法摘要

 boolean

**add**(E e)
          將指定的元素添加到此列表的尾部。

 void

**add**(int index,E element)
          將指定的元素插入此列表中的指定位置。

 boolean

**addAll**(Collection<? extendsE> c)
          按照指定 collection 的迭代器所返回的元素順序,將該 collection 中的全部元素添加到此列表的尾部。

 boolean

**addAll**(int index,Collection<? extendsE> c)
          從指定的位置開始,將指定 collection 中的全部元素插入到此列表中。

刪:

 E

**remove**(int index)
          移除此列表中指定位置上的元素。

 boolean

**remove**(Object o)
          移除此列表中首次出現的指定元素(若是存在)。

protected  void

**removeRange**(int fromIndex, int toIndex)
          移除列表中索引在fromIndex(包括)和toIndex(不包括)之間的全部元素。

void

**clear**()
          移除此列表中的全部元素。

查: 

 E

**get**(int index)
          返回此列表中指定位置上的元素。

 int

**indexOf**(Object o)
          返回此列表中首次出現的指定元素的索引,或若是此列表不包含元素,則返回 -1。

 boolean

**isEmpty**()
          若是此列表中沒有元素,則返回true

int

**size**()
          返回此列表中的元素數。

boolean

**contains**(Object o)
          若是此列表中包含指定的元素,則返回true。

ArrayList支持3種遍歷方式

第一種,經過迭代器遍歷

Integer value = null;
Iterator iter = list.iterator(); while (iter.hasNext()) {

value \= (Integer)iter.next();

}

 第二種,隨機訪問,經過索引值去遍歷。

Integer value = null;for (int i=0; i<list.size(); i++) {

value \= (Integer)list.get(i);

}

第三種,for-each遍歷

Integer value = null; for (Integer integ:list) {

value \= integ;

}

改:

 E

**set**(int index,E element)
          用指定的元素替代此列表中指定位置上的元素。

 Object[]

**toArray**()
   

HashMap

這裏咱們先講hashmap,具體緣由等講到hashset的時候就知道了。

  HashMap基於哈希表的 Map 接口實現,以key-value的形式存在。在HashMap中,系統 key-value 當成一個總體進行處理,系統老是根據 Hash 算法來計算 key-value 的存儲位置,這樣能夠保證能快速存、取 Map 的 key-value 對。系統調用key的 hashCode() 方法獲得其 hashCode 值——每一個 Java 對象都有 hashCode() 方法,均可經過該方法得到它的 hashCode 值。獲得這個對象的 hashCode 值以後,系統會根據該 hashCode 值來決定key—value的存儲位置。

建立:

構造方法摘要

**[HashMap](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#HashMap())**() 
          構造一個具備默認初始容量 (16) 和默認加載因子 (0.75) 的空 HashMap。

**[HashMap](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#HashMap(int))**(int initialCapacity) 
          構造一個帶指定初始容量和默認加載因子 (0.75) 的空 HashMap。

**[HashMap](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#HashMap(int,%20float))**(int initialCapacity, float loadFactor) 
          構造一個帶指定初始容量和加載因子的空 HashMap。

**[HashMap](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#HashMap(java.util.Map))**([Map](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/Map.html "java.util 中的接口")<? extends [K](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數"),? extends [V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")> m) 
          構造一個映射關係與指定 Map 相同的 HashMap。

 容量表示哈希表中桶的數量,初始容量是建立哈希表時的容量,加載因子是哈希表在其容量自動增長以前能夠達到多滿的一種尺度,它衡量的是一個散列表的空間的使用程度,負載因子越大表示散列表的裝填程度越高,反之愈小。

增:

[V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")

**[put](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#put(K,%20V))**([K](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數") key, [V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數") value) 
       插入鍵值對。

 void

**[putAll](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#putAll(java.util.Map))**([Map](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/Map.html "java.util 中的接口")<? extends [K](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數"),? extends [V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")> m) 
          把map中的鍵值對插入到hashmap中。

刪:

 [V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")

**[remove](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#remove(java.lang.Object))**([Object](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/lang/Object.html "java.lang 中的類") key) 
          若是此映射中存在該鍵的映射關係,則將其刪除。

 void

**[clear](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#clear())**() 
          今後映射中移除全部映射關係。

 查:

 [V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")

**[get](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#get(java.lang.Object))**([Object](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/lang/Object.html "java.lang 中的類") key) 
          返回指定鍵在此標識哈希映射中所映射的值,若是對於此鍵來講,映射不包含任何映射關係,則返回 null。

boolean

**[isEmpty](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#isEmpty())**() 
          若是此映射不包含鍵-值映射關係,則返回 true。

 [Set](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/Set.html "java.util 中的接口")<[K](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")>

**[keySet](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#keySet())**() 
          返回此映射中所包含的鍵的 set 。//獲取hashmap中的key集合。

[Collection](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/Collection.html "java.util 中的接口")<[V](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html "HashMap 中的類型參數")>

**[values](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#values())**() 
          返回此映射所包含的值的 collection 視圖。

 int

**[size](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#size())**() 
          返回此映射中的鍵-值映射關係數。

 boolean

**[containsKey](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#containsKey(java.lang.Object))**([Object](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/lang/Object.html "java.lang 中的類") key) 
          若是此映射包含對於指定的鍵的映射關係,則返回 true。

 boolean

**[containsValue](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/util/HashMap.html#containsValue(java.lang.Object))**([Object](http://www.gznc.edu.cn/yxsz/jjglxy/book/Java_api/java/lang/Object.html "java.lang 中的類") value) 
          若是此映射將一個或多個鍵映射到指定值,則返回 true。

HashSet

  HashSet是基於 HashMap 實現的,底層採用 HashMap 來保存數據。全部放入 HashSet 中的集合元素實際上由 HashMap 的 key 來保存,而 HashMap 的 value 則存儲了一個靜態的 Object 對象(向上轉型,這樣value就能夠是各類基本類型的值了)。HashSet 的絕大部分方法都是經過調用 HashMap 的方法來實現的,所以 HashSet 和 HashMap 兩個集合在實現本質上是相同的。 

建立:

HashSet hashSet = new HashSet();

HashSet hashset=new HashSet(collection);

增:

hashset.add(value);//向集合中添加一個元素

hashset.add(array[]);//把數組中的值添加到集合中

刪:

刪除一個元素:hashSet.remove(Object);

刪除全部元素:hashSet.clear();

查:

用迭代器遍歷:

複製代碼; "複製代碼")

Iterator it = hashSet.iterator();
while(it.hasNext()){
Object obj = it.next();

而後針對obj進行一系列的操做,好比:輸出值、若是obj是類對象則調用屬性、方法。

複製代碼; "複製代碼")

 boolean

**contains**(Object o)
          若是此 set 包含指定元素,則返回true。

 boolean

**isEmpty**()
          若是此 set 不包含任何元素,則返回true。

 int

**size**()
          返回此 set 中的元素的數量(set 的容量)。

 當從HashSet中訪問元素時,HashSet先計算該元素的hashCode值(也就是調用該對象的hashCode())方法的返回值),而後直接到該hashCode對應的位置去取出該元素。  爲了保證HashSet能正常工做,要求當兩個對象用equals比較相等時,hashCode也要相等,不然就會有可能加入兩個相同的項。

HashSet的特色:

(1)HashSet不是同步的,多個線程訪問是須要經過代碼保證同步

(2)集合元素值能夠爲null。

相關文章
相關標籤/搜索