1. 程式人生 > >集合的特點

集合的特點

由於 會員 art 切換 最大的 ble 關於 泛型 折扣

ArrayList的查詢效率比較高,增刪動作的效率比較差,適用於查詢比較頻繁,增刪動作較少的元素管理的集合。
ArrayList基礎object[]
LinkedList的查詢效率低,但是增刪效率很高。適用於增刪動作的比較頻繁,查詢次數較少的元素管理集合。
LinkedList鏈表???
?
接口
Collection
_____Set
_____SortedSet _____List

Map
?? |____SortedMap

Collection:集合層次中的根接口,JDK沒有提供這個接口的實現類.
Set:不能包含重復的元素.SortedSet是一個按照升序排列的元素的Set.

List:是一個有序的集合,可以包含重復的元素.提供了按索引訪問的
方式.
有次序,位置不改變.
Map:包含了key-value對.Map不能包含重復的key.SortedMap是一個
按升序排列key的Map.
存儲關鍵字和值.

???? 從早些時候的那幅示意圖可以看出,實際上只有三個集合組件:Map,List和Set。而且每個接口只有兩種或三種實施方案。若需使用由一個特定的接口提供的功能,如何才能決定到底采取哪一種方案呢?
為理解這個問題,必須認識到每種不同的實施方案都有自己的特點、優點和缺點。比如在那張示意圖中,可以看到Hashtable,Vector和Stack的“特點”是它們都屬於“傳統”類,所以不會幹擾原有的代碼。但在另一方面,應盡量避免為新的(Java 1.2)代碼使用它們。

其他集合間的差異通常都可歸納為它們具體是由什麽“後推”的。換言之,取決於物理意義上用於實施目標接口的數據結構是什麽。例如,ArrayList,LinkedList以及Vector(大致等價於ArrayList)都實現了List接口,所以無論選用哪一個,我們的程序都會得到類似的結果。然而,ArrayList(以及Vector)是由一個數組後推得到的;而LinkedList是根據常規的雙重鏈接列表方式實現的,因為每個單獨的對象都包含了數據以及指向列表內前後元素的句柄。正是由於這個原因,假如想在一個列表中部進行大量插入和刪除操作,那麽LinkedList無疑是最恰當的選擇(LinkedList還有一些額外的功能,建立於AbstractSequentialList中)。若非如此,就情願選擇ArrayList,它的速度可能要快一些。
作為另一個例子,Set既可作為一個ArraySet實現,亦可作為HashSet實現。ArraySet是由一個ArrayList後推得到的,設計成只支持少量元素,特別適合要求創建和刪除大量Set對象的場合使用。然而,一旦需要在自己的Set中容納大量元素,ArraySet的性能就會大打折扣。寫一個需要Set的程序時,應默認選擇HashSet。而且只有在某些特殊情況下(對性能的提升有迫切的需求),才應切換到ArraySet。

①決定使用何種List

在ArrayList中進行隨機訪問(即get())以及循環反復是最劃得來的;但對於LinkedList卻是一個不小的開銷。但另一方面,在列表中部進行插入和刪除操作對於LinkedList來說卻比ArrayList劃算得多。我們最好的做法也許是先選擇一個ArrayList作為自己的默認起點。以後若發現由於大量的插入和刪除造成了性能的降低,再考慮換成LinkedList不遲。

②決定使用何種set

進行add()以及contains()操作時,HashSet顯然要比ArraySet出色得多,而且性能明顯與元素的多寡關系不大。一般編寫程序的時候,幾乎永遠用不著使用ArraySet。

③決定使用何種Map
選擇不同的Map實施方案時,註意Map的大小對於性能的影響是最大的

即使大小為10,ArrayMap的性能也要比HashMap差——除反復循環時以外。而在使用Map時,反復的作用通常並不重要(get()通常是我們時間花得最多的地方)。TreeMap提供了出色的put()以及反復時間,但get()的性能並不佳。但是,我們為什麽仍然需要使用TreeMap呢?這樣一來,我們可以不把它作為Map使用,而作為創建順序列表的一種途徑。樹的本質在於它總是順序排列的,不必特別進行排序(它的排序方式馬上就要講到)。一旦填充了一個TreeMap,就可以調用keySet()來獲得鍵的一個Set“景象”。然後用toArray()產生包含了那些鍵的一個數組。隨後,可用static方法Array.binarySearch()快速查找排好序的數組中的內容。當然,也許只有在HashMap的行為不可接受的時候,才需要采用這種做法。因為HashMap的設計宗旨就是進行快速的檢索操作。最後,當我們使用Map時,首要的選擇應該是HashMap。只有在極少數情況下才需要考慮其他方法。

在寫這個程序期間,TreeMap的創建速度比其他兩種類型明顯快得多(但你應親自嘗試一下,因為據說新版本可能會改善ArrayMap的性能)。考慮到這方面的原因,同時由於前述TreeMap出色的put()性能,所以如果需要創建大量Map,而且只有在以後才需要涉及大量檢索操作,那麽最佳的策略就是:創建和填充TreeMap;以後檢索量增大的時候,再將重要的TreeMap轉換成HashMap——使用HashMap(Map)構建器。同樣地,只有在事實證明確實存在性能瓶頸後,才應關心這些方面的問題——先用起來,再根據需要加快速度。

Java容器類List、ArrayList、Vector及map、HashTable、HashMap分別的區別2007年04月16日 星期一 15:15Java容器類List、ArrayList、Vector及map、HashTable、HashMap分別的區別2007-03-06 17:06一、List與ArrayList的區別
???? List->AbstractList->ArrayList
???? (1) List是一個接口,ArrayList是一個實現了List接口的具體類。
???? 他們是父子關系,我們常用的是ArrayList,但常用List的引用去操作ArrayList
???? 這是一個簡單的面向接口編程的一種,如:List myList = new ArrayList();
???? (2)他們主要是用來保存對象的集合,記得是保存對象的哦,你可別傳個int(類)進去啊
???? (3)要取出它裏面保存的對象可以用下標,如:Object aaa = myList.get(0);
???? 這樣我們就把保存在myList裏的第一個對象取出來給了 aaa 啦。

二、祥解
????? ---------------------------1樓------------------------------------
???? 好像List和Map都是接口
???? 不能實例化的
???? 以前這麽寫List list = new Vector();
???? 現在這麽寫List list = new ArrayList();
???? 用ArrayList 代替了Vector 因為前者的性能比後者好;
???? 但是兩個都是實現了List借口的
???? 同理Map map = new HashTable();(以前)
???? Map map = new HashMap();(現在)
???? -------------------------------2樓-------------------------------
???? ArrayList和HashMap是異步的,Vector和HashTable是同步的,所以Vector和HashTable是線程安全的,而ArrayList和HashMap並不是線程安全的。因為同步需要花費機器時間,所以Vector和HashTable的執行效率要低於ArrayList和HashMap。
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

List接口
  List是有序的Collection,使用此接口能夠精確的控制每個元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。
和下面要提到的Set不同,List允許有相同的元素。
  除了具有Collection接口必備的iterator()方法外,List還提供一個listIterator()方法,返回一個ListIterator接口,和標準的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設定元素,還能向前或向後遍歷。
  實現List接口的常用類有LinkedList,ArrayList,Vector和Stack。
ArrayList類
  ArrayList實現了可變大小的數組。它允許所有元素,包括null。ArrayList沒有同步。
size,isEmpty,get,set方法運行時間為常數。但是add方法開銷為分攤的常數,添加n個元素需要O(n)的時間。其他的方法運行時間為線性。
  每個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小。這個容量可隨著不斷添加新元素而自動增加,但是增長算法並沒有定義。當需要插入大量元素時,在插入前可以調用ensureCapacity方法來增加ArrayList的容量以提高插入效率。
  和LinkedList一樣,ArrayList也是非同步的(unsynchronized)。
Map接口
  請註意,Map沒有繼承Collection接口,Map提供key到value的映射。一個Map中不能包含相同的key,每個key只能映射一個value。Map接口提供3種集合的視圖,Map的內容可以被當作一組key集合,一組value集合,或者一組key-value映射。
HashMap類
  HashMap和Hashtable類似,不同之處在於HashMap是非同步的,並且允許null,即null value和null key。,但是將HashMap視為Collection時(values()方法可返回Collection),其叠代子操作時間開銷和HashMap的容量成比例。因此,如果叠代操作的性能相當重要的話,不要將HashMap的初始化容量設得過高,或者load factor過低。
----------------------------------3樓------------------------------------------

  1. List是接口,List特性就是有序,會確保以一定的順序保存元素.
    ArrayList是它的實現類,是一個用數組實現的List.
    Map是接口,Map特性就是根據一個對象查找對象.
    HashMap是它的實現類,HashMap用hash表實現的Map,就是利用對象的hashcode(hashcode()是Object的方法)進行快速散列查找.(關於散列查找,可以參看<<數據結構>>)

  2. 一般情況下,如果沒有必要,推薦代碼只同List,Map接口打交道.
    比如:List list = new ArrayList();
    這樣做的原因是list就相當於是一個泛型的實現,如果想改變list的類型,只需要:
    List list = new LinkedList();//LinkedList也是List的實現類,也是ArrayList的兄弟類
    這樣,就不需要修改其它代碼,這就是接口編程的優雅之處.
    另外的例子就是,在類的方法中,如下聲明:
    private void doMyAction(List list){}
    這樣這個方法能處理所有實現了List接口的類,一定程度上實現了泛型函數.

  3. 如果開發的時候覺得ArrayList,HashMap的性能不能滿足你的需要,可以通過實現List,Map(或者Collection)來定制你的自定義類.
    可以參考The Art Of Computer Programming的Sorting and Searching部分

[矽步]Java中ArrayList和Vector的區別????
是的, 這是一個太多太多人遇到過, 討論過, 解釋過的問題.
為了加深自己的記憶, 還是決定寫一篇來記錄下他.

首先想說的是:
Vector是在Collections API之前就已經產生了的, 而ArrayList是在JDK1.2的時候才作為Collection framework的一部分引入的.? 它們都是在內部用一個Obejct[]來存儲元素的.

ok, 現在來說他們的差別:

  1. 線程安全
    Vector是同步的, 而ArrayList不是.
    因為Vector是同步的, 所以它是線程安全的.
    同樣, 因為Vecotr是同步的, 所以他需要額外的開銷來維持同步鎖, 所以它要比ArrayList要慢.(理論上來說)

當然, 如果你對ArrayList有偏好, 你也可以用Collection.synchronizedList(List)來得到一個線程安全的List.

  1. 容量增長
    Vector允許用戶設置capacityIncrement這樣在每次需要擴充數組的size的時候, Vector會嘗試按照預先設置的capacityIncrement作為增量來設置, 而ArrayList則會把數組的大小擴大一倍.

比如現在同樣一個長度為10的Vector和ArrayList, 我們把Vector的capacityIncrement設為1
那麽我們在插入第11個對象的時候, Vector會將長度變成11, 然後分配空間, 然後將對象添加進去, 而ArrayList則會分配20個對象的空間, 然後將對象添加進去.

如果capacityIncrement設為0或者負值, Vector就會做和ArrayList一樣, 每次都將數組大小擴大一倍.

  1. 性能比較
    剛剛在上面已經說過了, 由於Vector是同步的, 而ArrayList不是, 所以Vector的性能要比ArrayList要稍第一點, 用性能換安全嘛.

不過, 據Jack Shirazi在OnJava上的一篇文章來看, 似乎這並不是什麽問題, 他認為對於現在的JVM來說, 這兩個類在同步這個問題上的性能差異, 甚至還不如每次跑測試的時候環境變化引起的差異大.
Consequently Vector is thread-safe, and ArrayList isn‘t. This makes ArrayList faster than Vector. For some of the latest JVMs the difference in speed between the two classes is negligible: strictly speaking, for these JVMs the difference in speed between the two classes is less than the variation in times obtained from tests comparing the performance of these classes. ---- The Performance of Java‘s Lists

這樣看來, 性能上的差別應該不大.

So, as a conclusion.
結論和網上大多數人得到的結論一樣:
在一般情況下, 還是鼓勵用ArrayList的, 如果你有同步控制的需要, 那就用Vector吧, 也懶得用Collection.synchronizedList(List)再去轉一次了, 除非非這樣不可.. 不然還是順應潮流, 畢竟, 代碼是寫給人看的. 在無傷大雅的情況下, 按照common的法則來寫, 無疑會讓看代碼的人更快理解.

Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set

Collection接口
  Collection是最基本的集合接口,一個Collection代表一組Object,即Collection的元素(Elements)。一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子接口”如List和Set。
  所有實現Collection接口的類都必須提供兩個標準的構造函數:無參數的構造函數用於創建一個空的Collection,有一個Collection參數的構造函數用於創建一個新的Collection,這個新的Collection與傳入的Collection有相同的元素。後一個構造函數允許用戶復制一個Collection。
  如何遍歷Collection中的每一個元素?不論Collection的實際類型如何,它都支持一個iterator()的方法,該方法返回一個叠代子,使用該叠代子即可逐一訪問Collection中每一個元素。典型的用法如下:
    Iterator it = collection.iterator(); // 獲得一個叠代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一個元素
    }
  由Collection接口派生的兩個接口是List和Set。

List接口
  List是有序的Collection,這類似於Java的數組。 和下面要提到的Set不同,List允許有相同的元素。
  除了具有Collection接口必備的iterator()方法外,List還提供一個listIterator()方法,允許添加,刪除,設定元素,還能向前或向後遍歷。
  實現List接口的常用類有LinkedList,ArrayList,Vector和Stack。

LinkedList類
  LinkedList實現了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。
  註意LinkedList沒有同步方法。如果多個線程同時訪問一個List,則必須自己實現訪問同步。一種解決方法是在創建List時構造一個同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));

ArrayList類
  ArrayList實現了可變大小的數組。它允許所有元素,包括null。ArrayList沒有同步。size,isEmpty,get,set方法運行時間為常數。但是add方法開銷為分攤的常數,添加n個元素需要O(n)的時間。其他的方法運行時間為線性。
  每個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小。這個容量可隨著不斷添加新元素而自動增加,但是增長算法並沒有定義。當需要插入大量元素時,在插入前可以調用ensureCapacity方法來增加ArrayList的容量以提高插入效率。
  和LinkedList一樣,ArrayList也是非同步的(unsynchronized)。

Vector類
  Vector非常類似ArrayList,但是Vector是同步的。由Vector創建的Iterator,雖然和ArrayList創建的Iterator是同一接口,但是,因為Vector是同步的,當一個Iterator被創建而且正在被使用,另一個線程改變了Vector的狀態(例如,添加或刪除了一些元素),這時調用Iterator的方法時將拋出ConcurrentModificationException,因此必須捕獲該異常

Stack 類
  Stack繼承自Vector,實現一個後進先出的堆棧。

就ArrayList與Vector主要從二方面來說.
一.同步性:Vector是線程安全的,也就是說是同步的,而ArrayList是線程序不安全的,不是同步的
二.數據增長:當需要增長時,Vector默認增長為原來一培,而ArrayList卻是原來的一半

如果涉及到堆棧,隊列等操作,應該考慮用Vector,對於需要快速插入,刪除元素,應該使用LinkedList,如果需要快速隨機訪問元素,應該使用ArrayList

Vector還是ArrayList這是個問題
――比較Vector和ArrayList的不同

譯者語:那天一個好朋友問我Vector和ArrayList到底有什麽區別用那個好,自己也不是很清楚,於是乎搬出書看了個夠但是書裏也沒有專門對此進行比較,呵呵,索性黃天不負有心人,終於被我找到了問題的答案,這裏我把它翻譯過來,希望對大家有所幫助。有什麽翻譯的不對的地方還望指正:)
原文:http://www.javaworld.com/javaworld/javaqa/2001-06/03-qa-0622-vector.html?
Vector 還是ArrayList――哪一個更好,為什麽?
要回答這個問題不能一概而論,有時候使用Vector比較好;有時是ArrayList,有時候這兩個都不是最好的選擇。你別指望能夠獲得一個簡單肯定答案,因為這要看你用它們幹什麽。下面有4個要考慮的因素:
l??????? API
l??????? 同步處理
l??????? 數據增長性
l??????? 使用模式
下面針對這4個方面進行一一探討
API
在由Ken Arnold等編著的《Java Programming Language》(Addison-Wesley, June 2000)一書中有這樣的描述,Vector類似於ArrayList.。所有從API的角度來看這兩個類非常相似。但他們之間也還是有一些主要的區別的。

[b]同步性
Vector是同步的。這個類中的一些方法保證了Vector中的對象是線程安全的。而ArrayList則是異步的,因此ArrayList中的對象並不是線程安全的。因為同步的要求會影響執行的效率,所以如果你不需要線程安全的集合那麽使用ArrayList是一個很好的選擇,這樣可以避免由於同步帶來的不必要的性能開銷。
數據增長
從內部實現機制來講ArrayList和Vector都是使用數組(Array)來控制集合中的對象。當你向這兩種類型中增加元素的時候,如果元素的數目超出了內部數組目前的長度它們都需要擴展內部數組的長度,Vector缺省情況下自動增長原來一倍的數組長度,ArrayList是原來的50%,所以最後你獲得的這個集合所占的空間總是比你實際需要的要大。所以如果你要在集合中保存大量的數據那麽使用Vector有一些優勢,因為你可以通過設置集合的初始化大小來避免不必要的資源開銷。
使用模式
在ArrayList和Vector中,從一個指定的位置(通過索引)查找數據或是在集合的末尾增加、移除一個元素所花費的時間是一樣的,這個時間我們用O(1)表示。但是,如果在集合的其他位置增加或移除元素那麽花費的時間會呈線形增長:O(n-i),其中n代表集合中元素的個數,i代表元素增加或移除元素的索引位置。為什麽會這樣呢?以為在進行上述操作的時候集合中第i和第i個元素之後的所有元素都要執行位移的操作。這一切意味著什麽呢?
這意味著,你只是查找特定位置的元素或只在集合的末端增加、移除元素,那麽使用Vector或ArrayList都可以。如果是其他操作,你最好選擇其他的集合操作類。比如,LinkList集合類在增加或移除集合中任何位置的元素所花費的時間都是一樣的—O(1),但它在索引一個元素的使用缺比較慢-O(i),其中i是索引的位置.使用ArrayList也很容易,因為你可以簡單的使用索引來代替創建iterator對象的操作。LinkList也會為每個插入的元素創建對象,所有你要明白它也會帶來額外的開銷。
最後,在《Practical Java》一書中Peter Haggar建議使用一個簡單的數組(Array)來代替Vector或ArrayList。尤其是對於執行效率要求高的程序更應如此。因為使用數組(Array)避免了同步、額外的方法調用和不必要的重新分配空間的操作。

Java的數組(Array)、Vector、ArrayList、HashMap的異同作者: | 來源: | 時間:2007-12-06 | 閱讀權限:遊客身份 | 會員幣:0?
array(數組)和Vector是十分相似的Java構件(constructs),兩者全然不同,在選擇使用時應根據各自的功能來確定。

1、數組:Java arrays的元素個數不能下標越界,從很大程度上保證了Java程序的安全性,而其他一些語言出現這一問題時常導致災難性的後果。
??????? Array可以存放Object和基本數據類型,但創建時必須指定數組的大小,並不能再改變。值得註意的是:當Array中的某一元素存放的是Objrct reference 時,Java不會調用默認的構造函數,而是將其初值設為null,當然這跟Java對各類型數據賦默認值的規則是一樣的,對基本數據類型同樣適用。

2、Vector:對比於Array,當更多的元素被加入進來以至超出其容量時,Vector的size會動態增長,而Array容量是定死的。同時,Vector在刪除一些元素後,其所有下標大於被刪除元素的元素都依次前移,並獲得新下標比原來的小了)。註意:當調用Vector的size()方法時,返回Vector中實際元素的個數。
???? Vector內部實際是以Array實現的,也通過元素的整數索引來訪問元素,但它只能存放java.lang.Object對象,不能用於存放基本類型數據,比如要存放一個整數10,得用new Integer(10)構造出一個Integer包裝類對象再放進去。當Vector中的元素個數發生變化時, 其內部的Array必須重新分配並進行拷貝,因此這是一點值得考慮的效率問題。
???? Vetor同時也實現了List接口,所以也可以算作Colletion了,只是它還特殊在:Vector is synchronized。即Vetor對象自身實現了同步機制。

3、ArrayList:實現了List接口,功能與Vetor一樣,只是沒有同步機制,當然元素的訪問方式為從List中繼承而來,可存放任何類型的對象。

4、HashMap:繼承了Map接口,實現用Keys來存儲和訪問Values,Keys和Values都可以為空,它與Hashtable類的區別在於Hashtable類的Keys不能為null,並Hashtable類有同步機制控制,而HashMap類沒有。
????? 在Struts類庫中實現了一個LableValueBean,用Lable(Key)來存儲和訪問Value,很方便。

集合的特點