程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java:集合類性能分析

Java:集合類性能分析

編輯:關於JAVA

1.Java 集合框架圖

-集合接口:6個接口(短虛線表示),表示不同集合類型,是集合框架的基礎。

-抽象類:5個抽象類(長虛線表示),對集合接口的部分實現。可擴展為自定義集合類。

-實現類:8個實現類(實線表示),對接口的具體實現。

2.Java容器類介紹

① Java容器類都可以自動地調整自己的尺寸。

② Collection 接口是一組允許重復的對象。

③ Set 接口繼承 Collection,不允許重復,使用自己內部的一個排列機制。

④ List 接口繼承 Collection,允許重復,以元素安插的次序來放置元素,不會重新排列。

⑤ Map接口是一組成對的鍵-值對象,即所持有的是key-value pairs。Map中不能有重復的key。擁有自己的內部排列機制。

Java 2簡化集合框架圖

3.Collection接口

基本操作

-增加元素add(Object obj); addAll(Collection c);

-刪除元素 remove(Object obj); removeAll(Collection c);

-求交集 retainAll(Collection c);

Collection是最基本的集合接口,所有實現Collection接口的類都必須提供兩個標准的構造函數:無參數的構造函數用於創建一個空的Collection,有一個 Collection參數的構造函數用於創建一個新的Collection,這個新的Collection與傳入的Collection有相同類型的元素。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
public class AddingGroups {
  public static void main(String[] args) {
    Collection<Integer> collection = new ArrayList<Integer>(Arrays.asList(
       1, 2, 3, 4, 5));
    Integer[] moreInts={6,7,8,9,10};
    collection.addAll(Arrays.asList(moreInts));
    for (Integer i : collection)
      System.out.print(i + ",");
  }
}

結果:

1,2,3,4,5,6,7,8,9,10,

這裡展示了Collection接口的2個用法,首先,Collection構造函數接受另一個Collection(List)作為參數,使其初始化。接著,調用addAll()方法添加元素,注意,該方法只接受另一個Collection作為參數。

此外,必須注意,Collection接口不提供隨機訪問元素的get()方法。因為Collection包括Set,而Set自己維護內部順序。如果想檢查Collection中的元素,那就必須使用迭代器。

4.List接口

4.1 List接口

List是有序的Collection,使用此接口能夠精確的控制每個元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。

和下面要提到的Set不同,List允許有相同的元素。

除了具有Collection接口必備的iterator()方法外,List還提供一個listIterator()方法,返回一個 ListIterator接口,和標准的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設定元素, 還能向前或向後遍歷。

4.2 LinkedList類

LinkedList實現了List接口,允許null元素。此外LinkedList提供額外的get,remove,insert方法在 LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。此實現不是同步的。

4.3 ArrayList類

ArrayList實現了可變大小的數組。它允許所有元素,包括null。

size,isEmpty,get,set方法運行時間為常數。但是add方法開銷為分攤的常數,添加n個元素需要O(n)的時間。其他的方法運行時間為線性。

每個ArrayList實例都有一個容量(Capacity),即用於存儲元素的數組的大小。這個容量可隨著不斷添加新元素而自動增加,但是增長算法並沒有定義。當需要插入大量元素時,在插入前可以調用ensureCapacity方法來增加ArrayList的容量以提高插入效率。此實現不是同步的。

5.Set接口

5.1 Set接口

Set具有和Collection完全一樣的接口,沒有任何額外的功能。它是一種不包含重復的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。

很明顯,Set的構造函數有一個約束條件,傳入的Collection參數不能包含重復的元素。

請注意:必須小心操作可變對象(Mutable Object)。如果一個Set中的可變元素改變了自身狀態導致Object.equals(Object)=true將導致一些問題。

5.2 HashSet

此類實現Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。此類為基本操作提供了穩定性能,此實現不是同步的。

5.3 LinkedHashSet

具有可預知迭代順序的Set 接口的哈希表和鏈接列表實現。此實現與HashSet的不同之處在於,它維護著一個運行於所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,即按照將元素插入到set中的順序(插入順序)進行迭代。注意,插入順序不受在set中重新插入的元素影響。此實現不是同步的。

5.4 TreeSet

基於TreeMap的NavigableSet實現。使用元素的自然順序對元素進行排序,或者根據創建set時提供的 Comparator 進行排序,具體取決於使用的構造方法。此實現為基本操作(add、remove 和 contains)提供受保證的 log(n) 時間開銷。此實現不是同步的。

6.Map接口

請注意,Map沒有繼承Collection接口,Map提供key到value的映射。一個Map中不能包含相同的key,每個key只能映射一個 value。Map接口提供3種集合的視圖,Map的內容可以被當作一組key集合,一組value集合,或者一組key-value映射。

6.1 WeakHashMap

以弱鍵實現的基於哈希表的Map。在WeakHashMap中,當某個鍵不再正常使用時,將自動移除其條目。更精確地說,對於一個給定的鍵,其映射的存在並不阻止垃圾回收器對該鍵的丟棄,這就使該鍵成為可終止的,被終止,然後被回收。丟棄某個鍵時,其條目從映射中有效地移除,因此,該類的行為與其他的Map實現有所不同。此實現不是同步的。

6.2 TreeMap

該映射根據其鍵的自然順序進行排序,或者根據創建映射時提供的Comparator進行排序,具體取決於使用的構造方法。此實現不是同步的。

6.3 HashMap

基於哈希表的Map接口的實現。此實現提供所有可選的映射操作,並允許使用 null 值和 null 鍵。(除了非同步和允許使用null之外,HashMap 類與 Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恆久不變。此實現不是同步的。

6.4 SortedMap

進一步提供關於鍵的總體排序的Map。該映射是根據其鍵的自然順序進行排序的,或者根據通常在創建有序映射時提供的Comparator進行排序。對有序映射的collection 視圖(由 entrySet、keySet 和 values 方法返回)進行迭代時,此順序就會反映出來。要采用此排序方式,還需要提供一些其他操作(此接口是 SortedSet 的對應映射)。

7.集合類性能效率總結

注意,這裡展示的類都是非線程安全的。如果需要考慮線程安全,應該使用ConcurrentMap,CopyOnWriteArrayList,CopyOnWriteArraySet等。

接口 實現類 保持插入順序 可重復 排序 使用說明 List ArrayList Y Y N 長於隨機訪問元素;但插入、刪除元素較慢(數組特性)。 LinkedList Y Y N 插入、刪除元素較快,但隨即訪問較慢(鏈表特性)。 Set HashSet N N N 使用散列,最快的獲取元素方法。 TreeSet N N Y 將元素存儲在紅-黑樹數據結構中。默認為升序。 LinkedHashSet Y N N 使用散列,同時使用鏈表來維護元素的插入順序。 Map HashMap N N N 使用散列,提供最快的查找技術。 TreeMap N N Y 默認按照比較結果的升序保存鍵。 LinkedHashMap Y N N 按照插入順序保存鍵,同時使用散列提高查找速度。

總結

①如果涉及到堆棧,隊列等操作,應該考慮用List。如果要進行大量的隨機訪問,應使用ArrayList;如果經常進行插入與刪除操作,用使用LinkedList。

②HashMap設計用來快速訪問;而TreeMap保持“鍵”始終處於排序狀態,所以沒有HashMap快。LinkedHashMap保持元素插入的順序,但是也通過散列提供了快速訪問能力。

③Set不接受重復元素。HashSet提供最快的查詢速度,而TreeSet保持元素處於排序狀態。LinkedHashSet以插入順序保存元素。

④對哈希表的操作,作為key的對象要正確重寫equals和hashCode方法。

⑤盡量返回接口而非實際的類型(針對抽象編程),如返回List而非ArrayList,這樣如果以後需要將ArrayList換成LinkedList時,客戶端代碼不用改變。

⑥程序中不應該使用過時的Vector\Hashtable\Stack。

本文出自 “子 孑” 博客,請務必保留此出處http://zhangjunhd.blog.51cto.com/113473/69677

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved