Java-常-用-集-合

java 代碼

import java.util.List;   
import java.util.ArrayList;   
import java.util.LinkedList;   
  
import java.util.Map;   
import java.util.HashMap;   
import java.util.LinkedHashMap;   
import java.util.TreeMap;
  
import java.util.Set;   
import java.util.HashSet;   
import java.util.LinkedHashSet;   
import java.util.TreeSet;
  
import java.util.Vector;   
import java.util.Hashtable;  

1、java.util.ArrayList

List 接口的大小可變數組的實現。實現了所有可選列表操作,並允許包括 null 在內的所有元素。除了實現 List 接口外,此類還提供一些方法來操作內部用來存儲列表的數組的大小。(此類大致上等同於 Vector 類,除了此類是不同步的。)

size、isEmpty、get、set、iterator 和 listIterator 操作都以固定時間運行。add 操作以分攤的固定時間 運行,也就是說,添加 n 個元素需要 O(n) 時間。其他所有操作都以線性時間運行(大體上講)。與用於 LinkedList 實現的常數因子相比,此實現的常數因子較低。

每個 ArrayList 實例都有一個容量。該容量是指用來存儲列表元素的數組的大小。它總是至少等於列表的大小。隨着向 ArrayList 中不斷添加元素,其容量也自動增長。並未指定增長策略的細節,因爲這不只是添加元素會帶來分攤固定時間開銷那樣簡單。

在添加大量元素前,應用程序可以使用 ensureCapacity 操作來增加 ArrayList 實例的容量。這可以減少遞增式再分配的數量。

注意,此實現不是同步的。如果多個線程同時訪問一個 ArrayList 實例,而其中至少一個線程從結構上修改了列表,那麼它必須 保持外部同步。(結構上的修改是指任何添加或刪除一個或多個元素的操作,或者顯式調整底層數組的大小;僅僅設置元素的值不是結構上的修改。)這一般通過對自然封裝該列表的對象進行同步操作來完成。如果不存在這樣的對象,則應該使用 Collections.synchronizedList 方法將該列表“包裝”起來。這最好在創建時完成,以防止意外對列表進行不同步的訪問:

        List list = Collections.synchronizedList(new ArrayList(...));
此類的 iterator 和 listIterator 方法返回的迭代器是快速失敗的:在創建迭代器之後,除非通過迭代器自身的 remove 或 add 方法從結構上對列表進行修改,否則在任何時間以任何方式對列表進行修改,迭代器都會拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就會完全失敗,而不是冒着在將來某個不確定時間發生任意不確定行爲的風險。

注意,迭代器的快速失敗行爲無法得到保證,因爲一般來說,不可能對是否出現不同步併發修改做出任何硬性保證。快速失敗迭代器會盡最大努力拋出 ConcurrentModificationException。因此,爲提高這類迭代器的正確性而編寫一個依賴於此異常的程序是錯誤的做法:迭代器的快速失敗行爲應該僅用於檢測 bug。

此類是 Java Collections Framework 的成員。

Since: 1.2

2、java.util.LinkedList
List 接口的鏈接列表實現。實現所有可選的列表操作,並且允許所有元素(包括 null)。除了實現 List 接口外,LinkedList 類還爲在列表的開頭及結尾 get、remove 和 insert 元素提供了統一的命名方法。這些操作允許將鏈接列表用作堆棧、隊列或雙端隊列 (deque)。

此類實現 Queue 接口,爲 add、poll 等提供先進先出隊列操作。其他堆棧和雙端隊列操作可以根據標準列表操作方便地進行再次強制轉換。雖然它們可能比等效列表操作運行稍快,但是將其包括在這裏主要是出於方便考慮。

所有操作都是按照雙重鏈接列表的需要執行的。在列表中編索引的操作將從開頭或結尾遍歷列表(從靠近指定索引的一端)。

注意,此實現不是同步的。如果多個線程同時訪問列表,而其中至少一個線程從結構上修改了該列表,則它必須 保持外部同步。(結構修改指添加或刪除一個或多個元素的任何操作;僅設置元素的值不是結構修改。)這一般通過對自然封裝該列表的對象進行同步操作來完成。如果不存在這樣的對象,則應該使用 Collections.synchronizedList 方法來“包裝”該列表。最好在創建時完成這一操作,以防止對列表進行意外的不同步訪問,如下所示:

     List list = Collections.synchronizedList(new LinkedList(...));

此類的 iterator 和 listIterator 方法返回的迭代器是快速失敗 的:在迭代器創建之後,如果從結構上對列表進行修改,除非通過迭代器自身的 remove 或 add 方法,其他任何時間任何方式的修改,迭代器都將拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就會完全失敗,而不冒將來不確定的時間任意發生不確定行爲的風險。

注意,迭代器的快速失敗行爲不能得到保證,一般來說,存在不同步的併發修改時,不可能作出任何硬性保證。快速失敗迭代器盡最大努力拋出 ConcurrentModificationException。因此,編寫依賴於此異常的程序的方式是錯誤的,正確做法是:迭代器的快速失敗行爲應該僅用於檢測程序錯誤。

此類是 Java Collections Framework 的成員。

Since: 1.2

3、Vector 類提供了實現可增長數組的功能,隨着更多元素加入其中,數組變的更大。在刪除一些元素之後,數組變小。

java.util.Vector
java.lang.Object
  java.util.AbstractCollection
      java.util.AbstractList
          java.util.Vector

所有已實現的接口:
Serializable, Cloneable, Iterable, Collection, List, RandomAccess
直接子類:Stack
Vector 類可以實現可增長的對象數組。與數組一樣,它包含可以使用整數索引進行訪問的組件。但是,Vector 的大小可以根據需要增大或縮小,以適應創建 Vector 後進行添加或移除項的操作。

每個向量會試圖通過維護 capacity 和 capacityIncrement 來優化存儲管理。capacity 始終至少應與向量的大小相等;這個值通常比後者大些,因爲隨着將組件添加到向量中,其存儲將按 capacityIncrement 的大小增加存儲塊。應用程序可以在插入大量組件前增加向量的容量;這樣就減少了增加的重分配的量。

從 Java 2 平臺 v1.2 開始,已改進此類以實現 List,這樣它就成爲了 Java 的集合框架的一部分。與新集合的實現不同,Vector 是同步的。

由 Vector 的 iterator 和 listIterator 方法所返回的迭代器是快速失敗的:如果在迭代器創建後的任意時間從結構上修改了向量(通過迭代器自身的 remove 或 add 方法之外的任何其他方式),則迭代器將拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就完全失敗,而不是冒着在將來不確定的時間任意發生不確定行爲的風險。Vector 的 elements 方法返回的 Enumeration 不是 快速失敗的。

注意,迭代器的快速失敗行爲不能得到保證,一般來說,存在不同步的併發修改時,不可能作出任何堅決的保證。快速失敗迭代器盡最大努力拋出 ConcurrentModificationException。因此,編寫依賴於此異常的程序的方式是錯誤的,正確做法是:迭代器的快速失敗行爲應該僅用於檢測 bug。
  Vector 有三個構造函數:

  public Vector(int initialCapacity,int capacityIncrement)
  public Vector(int initialCapacity)
  public Vector()

  Vector 運行時創建一個初始的存儲容量initialCapacity,存儲容量是以capacityIncrement 變量定義的增量增長。初始的存儲容量和capacityIncrement 可以在Vector 的構造函數中定義。第二個構造函數只創建初始存儲容量。第三個構造函數既不指定初始的存儲容量也不指定capacityIncrement。

  Vector 類提供的訪問方法支持類似數組運算和與Vector 大小相關的運算。類似數組的運算允許向量中增加,刪除和插入元素。它們也允許測試矢量的內容和檢索指定的元素,與大小相關的運算允許判定字節大小和矢量中元素不數目。

4、java.util.Hashtable

java.lang.Object
java.util.Dictionary
      java.util.Hashtable


所有已實現的接口:
Serializable, Cloneable, Map
直接已知子類:
Properties, UIDefaults
此類實現一個哈希表,該哈希表將鍵映射到相應的值。任何非 null 對象都可以用作鍵或值。

爲了成功地在哈希表中存儲和檢索對象,用作鍵的對象必須實現 hashCode 方法和 equals 方法。

Hashtable 的實例有兩個參數影響其性能:初始容量 和加載因子。容量 是哈希表中桶 的數量,初始容量 就是哈希表創建時的容量。注意,哈希表的狀態爲 open:在發生“哈希衝突”的情況下,單個桶會存儲多個條目,這些條目必須按順序搜索。加載因子 是對哈希表在其容量自動增加之前可以達到多滿的一個尺度。初始容量和加載因子這兩個參數只是對該實現的提示。關於何時以及是否調用 rehash 方法的具體細節則依賴於該實現。

通常,默認加載因子(.75)在時間和空間成本上尋求一種折衷。加載因子過高雖然減少了空間開銷,但同時也增加了查找某個條目的時間(在大多數 Hashtable 操作中,包括 get 和 put 操作,都反映了這一點)。

初始容量主要控制空間消耗與執行 rehash 操作所需要的時間損耗之間的平衡。如果初始容量大於 Hashtable 所包含的最大條目數除以加載因子,則永遠 不會發生 rehash 操作。但是,將初始容量設置太高可能會浪費空間。

如果很多條目要存儲在一個 Hashtable 中,那麼與根據需要執行自動 rehashing 操作來增大表的容量的做法相比,使用足夠大的初始容量創建哈希表或許可以更有效地插入條目。

下面這個示例創建了一個數字的哈希表。它將數字的名稱用作鍵:

     Hashtable numbers = new Hashtable();
     numbers.put("one", new Integer(1));
     numbers.put("two", new Integer(2));
     numbers.put("three", new Integer(3));
要檢索一個數字,可以使用以下代碼:

   Integer n = (Integer)numbers.get("two");
      if (n != null) {
            System.out.println("two = " + n);
      }
自 Java 2 平臺 v1.2 以來,此類已經改進爲可以實現 Map,因此它變成了 Java Collections Framework 的一部分。與新集合的實現不同,Hashtable 是同步的。

由迭代器返回的 Iterator 和由所有 Hashtable 的“collection 視圖方法”返回的 Collection 的 listIterator 方法都是快速失敗 的:在創建 Iterator 之後,如果從結構上對 Hashtable 進行修改,除非通過 Iterator 自身的移除或添加方法,否則在任何時間以任何方式對其進行修改,Iterator 都將拋出 ConcurrentModificationException。因此,面對併發的修改,Iterator 很快就會完全失敗,而不冒在將來某個不確定的時間發生任意不確定行爲的風險。由 Hashtable 的鍵和值方法返回的 Enumeration 不 是快速失敗的。

注意,迭代器的快速失敗行爲無法得到保證,因爲一般來說,不可能對是否出現不同步併發修改做出任何硬性保證。快速失敗迭代器會盡最大努力拋出 ConcurrentModificationException。因此,爲提高這類迭代器的正確性而編寫一個依賴於此異常的程序是錯誤做法:迭代器的快速失敗行爲應該僅用於檢測程序錯誤。

此類是 Java Collections Framework 的成員。

5、java.util.HashMap
java.lang.Object
  java.util.AbstractMap
      java.util.HashMap

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

此實現假定哈希函數將元素正確分佈在各桶之間,可爲基本操作(get 和 put)提供穩定的性能。迭代集合視圖所需的時間與 HashMap 實例的“容量”(桶的數量)及其大小(鍵-值映射關係數)的和成比例。所以,如果迭代性能很重要,則不要將初始容量設置得太高(或將加載因子設置得太低)。

HashMap 的實例有兩個參數影響其性能:初始容量 和加載因子。容量 是哈希表中桶的數量,初始容量只是哈希表在創建時的容量。加載因子 是哈希表在其容量自動增加之前可以達到多滿的一種尺度。當哈希表中的條目數超出了加載因子與當前容量的乘積時,通過調用 rehash 方法將容量翻倍。

通常,默認加載因子 (.75) 在時間和空間成本上尋求一種折衷。加載因子過高雖然減少了空間開銷,但同時也增加了查詢成本(在大多數 HashMap 類的操作中,包括 get 和 put 操作,都反映了這一點)。在設置初始容量時應該考慮到映射中所需的條目數及其加載因子,以便最大限度地降低 rehash 操作次數。如果初始容量大於最大條目數除以加載因子,則不會發生 rehash 操作。

如果很多映射關係要存儲在 HashMap 實例中,則相對於按需執行自動的 rehash 操作以增大表的容量來說,使用足夠大的初始容量創建它將使得映射關係能更有效地存儲。

注意,此實現不是同步的。如果多個線程同時訪問此映射,而其中至少一個線程從結構上修改了該映射,則它必須 保持外部同步。(結構上的修改是指添加或刪除一個或多個映射關係的操作;僅改變與實例已經包含的鍵關聯的值不是結構上的修改。)這一般通過對自然封裝該映射的對象進行同步操作來完成。如果不存在這樣的對象,則應該使用 Collections.synchronizedMap 方法來“包裝”該映射。最好在創建時完成這一操作,以防止對映射進行意外的不同步訪問,如下所示:

 Map m = Collections.synchronizedMap(new HashMap(...));

由所有此類的“集合視圖方法”所返回的迭代器都是快速失敗 的:在迭代器創建之後,如果從結構上對映射進行修改,除非通過迭代器自身的 remove 或 add 方法,其他任何時間任何方式的修改,迭代器都將拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就會完全失敗,而不冒在將來不確定的時間任意發生不確定行爲的風險。

注意,迭代器的快速失敗行爲不能得到保證,一般來說,存在不同步的併發修改時,不可能作出任何堅決的保證。快速失敗迭代器盡最大努力拋出 ConcurrentModificationException。因此,編寫依賴於此異常程序的方式是錯誤的,正確做法是:迭代器的快速失敗行爲應該僅用於檢測程序錯誤。

此類是 Java Collections Framework 的成員。

6、java.util.TreeMap
java.lang.Object
  java.util.AbstractMap
      java.util.TreeMap

所有已實現的接口:Serializable, Cloneable, Map, SortedMap
SortedMap 接口的基於紅黑樹的實現。此類保證了映射按照升序順序排列關鍵字,根據使用的構造方法不同,可能會按照鍵的類的自然順序 進行排序(參見 Comparable),或者按照創建時所提供的比較器進行排序。

此實現爲 containsKey、get、put 和 remove 操作提供了保證的 log(n) 時間開銷。這些算法是 Cormen、Leiserson 和 Rivest 的《Introduction to Algorithms》中的算法的改編。

注意,如果有序映射要正確實現 Map 接口,則有序映射所保持的順序(無論是否明確提供比較器)都必須保持與等號一致。(請參見與等號一致 的精確定義的 Comparable 或 Comparator。)這也是因爲 Map 接口是按照等號操作定義的,但映射使用它的 compareTo(或 compare)方法對所有鍵進行比較,因此從有序映射的觀點來看,此方法認爲相等的兩個鍵就是相等的。即使順序與等號不一致,有序映射的行爲仍然是 定義良好的;只不過沒有遵守 Map 接口的常規約定。

注意,此實現不是同步的。如果多個線程同時訪問一個映射,並且其中至少一個線程從結構上修改了該映射,則其必須 保持外部同步。(結構上修改是指添加或刪除一個或多個映射關係的操作;僅改變與現有鍵關聯的值不是結構上的修改。)這一般通過對自然封裝該映射的某個對象進行同步操作來完成。如果不存在這樣的對象,則應該使用 Collections.synchronizedMap 方法來“包裝”該映射。最好在創建時完成這一操作,以防止對映射進行意外的不同步訪問,如下所示:

     Map m = Collections.synchronizedMap(new TreeMap(...));

由所有此類的“collection 視圖方法”所返回的迭代器都是快速失敗 的:在迭代器創建之後,如果從結構上對映射進行修改,除非通過迭代器自身的 remove 或 add 方法,其他任何時間任何方式的修改,迭代器都將拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就完全失敗,而不是冒着在將來不確定的時間任意發生不確定行爲的風險。

注意,迭代器的快速失敗行爲無法得到保證,因爲一般來說,不可能對是否出現不同步併發修改做出任何硬性保證。快速失敗迭代器會盡最大努力拋出 ConcurrentModificationException。因此,爲提高這類迭代器的正確性而編寫一個依賴於此異常的程序是錯誤的做法:迭代器的快速失敗行爲應該僅用於檢測 bug。

此類是Java Collections Framework 的成員。

從以下版本開始: 1.2
7、java.util.TreeSet

java.lang.Object
  java.util.AbstractCollection
      java.util.AbstractSet
          java.util.TreeSet

所有已實現的接口:Serializable, Cloneable, Iterable, Collection, Set, SortedSet
此類實現 Set 接口,該接口由 TreeMap 實例支持。此類保證排序後的 set 按照升序排列元素,根據使用的構造方法不同,可能會按照元素的自然順序 進行排序(參見 Comparable),或按照在創建 set 時所提供的比較器進行排序。

此實現爲基本操作(add、remove 和 contains)提供了可保證的 log(n) 時間開銷。

注意,如果要正確實現 Set 接口,則 set 所維護的順序(是否提供了顯式比較器)必須爲與等號一致(請參閱與等號一致 精確定義的 Comparable 或 Comparator)。這是因爲 Set 接口根據 equals 操作進行定義,但 TreeSet 實例將使用其 compareTo(或 compare)方法執行所有的鍵比較,因此,從 set 的角度出發,該方法認爲相等的兩個鍵就是相等的。即使 set 的順序與等號不一致,其行爲也是 定義良好的;它只是違背了 Set 接口的常規協定。

注意,此實現不是同步的。如果多個線程同時訪問一個 set,而其中至少一個線程修改了該 set,那麼它必須 保持外部同步。通常通過對某個自然封裝該 set 的對象進行同步來實現此操作。如果不存在此類對象,則 set 就應該使用 Collections.synchronizedSet 方法進行“包裝”。此操作最好在創建時進行,以防止對 set 的意外非同步訪問:

     SortedSet s = Collections.synchronizedSortedSet(new TreeSet(...));
此類的 iterator 方法返回的迭代器是快速失敗的:如果在迭代器創建後的任意時間修改 set(通過迭代器本身 remove 方法之外的任何其他方式),迭代器將拋出 ConcurrentModificationException。因此,在併發修改時,迭代器將快速而徹底地失敗,而不會在以後的不確定時間有出現任意、無法確定行爲的危險。

 


注意,無法保證迭代器的快速失敗行爲,因爲通常來說,不可能在非同步併發修改的情況下提供任何硬性保證。快速失敗的迭代器將盡量拋出 ConcurrentModificationException。因此,爲了獲得其準確性而編寫依賴此異常的程序的做法是錯誤的:迭代器的快速失敗行爲應當僅用於檢測 bug。

此類是Java Collections Framework 的成 員。

 

從以下版本開始:1.2
8、java.util.HashSet
java.lang.Object
  java.util.AbstractCollection
      java.util.AbstractSet
          java.util.HashSet

所有已實現的接口:
Serializable, Cloneable, Iterable, Collection, Set
直接已知子類:
JobStateReasons, LinkedHashSet
此類實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。它不保證集合的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。

此類爲基本操作提供了穩定性能,這些基本操作包括 add、remove、contains 和 size,假定哈希函數將這些元素正確地分佈在桶中。對此集合進行迭代所需的時間與 HashSet 實例的大小(元素的數量)和底層 HashMap 實例(桶的數量)的“容量”的和成比例。因此,如果迭代性能很重要,則不要將初始容量設置得太高(或將加載因子設置得太低)。

注意,此實現不是同步的。 如果多個線程同時訪問一個集合,而其中至少一個線程修改了該集合,那麼它必須 保持外部同步。這通常是通過對自然封裝該集合的對象執行同步操作來完成的。如果不存在這樣的對象,則應該使用 Collections.synchronizedSet 方法來“包裝”集合。最好在創建時完成這一操作,以防止對 HashSet 實例進行意外的不同步訪問:

     Set s = Collections.synchronizedSet(new HashSet(...));
此類的 iterator 方法返回的迭代器是快速失敗 的:在創建迭代器之後,如果對集合進行修改,除非通過迭代器自身的 remove 方法,否則在任何時間以任何方式對其進行修改,Iterator 都將拋出 ConcurrentModificationException。因此,面對併發的修改,迭代器很快就會完全失敗,而不冒將來在某個不確定時間發生任意不確定行爲的風險。

注意,迭代器的快速失敗行爲無法得到保證,因爲一般來說,不可能對是否出現不同步併發修改做出任何硬性保證。快速失敗迭代器在盡最大努力拋出 ConcurrentModificationException。因此,爲提高這類迭代器的正確性而編寫一個依賴於此異常的程序是錯誤做法:迭代器的快速失敗行爲應該僅用於檢測程序錯誤。

此類是Java Collections Framework 的成員。

 

-------------------------------Java常用集合

 

java集合類的使用           

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.

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

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

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

3. 性能比較
剛剛在上面已經說過了, 由於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,很方便。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章