Java 集合框架(常用數據結構)


早在Java 2中之前,Java就提供了特設類。比如:向量(Vector)、棧(Stack)、字典(Dictionary)、哈希表(Hashtable)這些類(數據結構)用來存儲和操作對象組。雖然這些類都非常有用,但是它們缺少一個核心的,統一的主題。集合框架是為表示和操作集合而規定的一種統一的標准的體系結構。除了集合,該框架(framework)也定義了幾個Map接口和類。Map里存儲的是鍵/值對。盡管Map不是collections,但是它們完全整合在集合中。

所有的集合框架都包含如下內容:

  • 接口:是代表集合的抽象數據類型。接口允許集合獨立操縱其代表的細節。在面向對象的語言,接口通常形成一個層次。
  • 實現(類):是集合接口的具體實現。從本質上講,它們是可重復使用的數據結構。
  • 算法:是實現集合接口的對象里的方法執行的一些有用的計算,例如:搜索和排序。這些算法被稱為多態,那是因為相同的方法可以在相似的接口上有着不同的實現。

集合框架的類和接口均在java.util包中。

下圖是簡化的集合框架關系圖:
集合框架

集合接口

整個集合框架就圍繞一組標准接口而設計。你可以直接使用這些接口的標准實現,諸如: LinkedList, HashSet, 和 TreeSet等,除此之外你也可以通過這些接口實現自己的集合。具體接口及其概述如下:

名稱 概述
Collection Collection 是最基本的集合接口,一個 Collection 代表一組 Object,Java不提供直接繼承自Collection的類,只提供繼承於的子接口(如List和set)。
List List接口是一個有序的Collection,使用此接口能夠精確的控制每個元素插入的位置,能夠通過索引(元素在List中位置,類似於數組的小標)來訪問List中的元素,而且允許有相同的元素。
Set Set 具有與 Collection 完全一樣的接口,只是行為上不同,Set 不保存重復的元素
SortedSet 繼承於Set保存有序的集合。
Map 將唯一的鍵映射到值。
Map.Entry 描述在一個Map中的一個元素(鍵/值對)。是一個Map的內部類。
SortedMap 繼承於Map,使Key保持在升序排列。
Enumeration 這是一個傳統的接口和定義的方法,通過它可以枚舉(一次獲得一個)對象集合中的元素。這個傳統接口已被迭代器取代。

更多參見:在線文檔-jdk-zh

集合實現類

集合類型 描述
ArrayList 一種可以動態增長和縮減的索引序列
LinkedList 一種可以在任何位置進行高效地插入和刪除操作的有序序列
ArrayDeque 一種用循環數組實現的雙端隊列
HashSet 一種沒有重復元素的無序集合
TreeSet 一種有序集
EnumSet 一種包含枚舉類型值的集
LinkedHashSet 一種可以記住元素插入次序的集
PriorityQueue 一種允許高效刪除最小元素的集合
HashMap 一種儲存鍵/值關聯的數據結構
TreeMap 一種鍵值有序排列的映射表
EnumMap 一種鍵值屬於枚舉類型的映射表
WeakHashMap 一種其值誒用武之地后可以被垃圾回收器回收的映射表
LinkedHashMap 一種可以記住鍵/值項添加次序的映射表
IdentityHashMap 一種用==,而不是用equals比較鍵值的映射表

另外還有一組名字以Abstract開頭的類,例如,AbstractQueue,這些類是為類庫實現者而設計的,用來實現自己的數據結構。

常用數據結構

  • 向量(Vector)

Vector類實現了一個動態數組。和ArrayList和相似,但是Vector是同步訪問的(同步操作會耗費大量時間,建議在不需要同步時使用ArrayList),而且Vector包含了許多傳統的方法,這些方法不屬於集合框架。Vector主要用在事先不知道數組的大小,或者只是需要一個可以改變大小的數組的情況。需要注意的是向量中的數據被轉化為Object對象,取出元素使用時要強制轉化為原來的類型。

Vector類支持4種構造方法:

Vector();  //默認大小為10

Vector(int size);   //創建指定大小的向量

Vector(int size,int incr);  //指定大小和增量,增量表示向量每次增加的元素數目

Vector(Collection c);   //創建一個包含集合c元素的向量

常用方法:

| 方法 | 描述 |
|------|------|
|  boolean	add(E e) | 將指定元素添加到此向量的末尾。 |
| void	add(int index, E element) | 在此向量的指定位置插入指定的元素。  |
|  E	remove(int index) |移除此向量中指定位置的元素。 | 
| boolean	remove(Object o) | 移除此向量中指定元素的第一個匹配項,不包含則元素保持不變。 |
|  E	set(int index, E element)  | 用指定的元素替換此向量中指定位置處的元素。 |
| void	setElementAt(E obj, int index) | 將此向量指定 index 處的組件設置為指定的對象。 |
|  E get(int index) | 返回向量中指定位置的元素。 |
| int	indexOf(Object o) | 返回此向量中第一次出現的指定元素的索引,不包含則返回 -1。 |
|  boolean	isEmpty() | 測試此向量是否不包含組件。 |
| void	clear() | 從此向量中移除所有元素。 |
| int	capacity() | 返回此向量的當前容量。 |
| boolean	contains(Object o) | 如果此向量包含指定的元素,則返回 true。 |
| void	setSize(int newSize) | 設置此向量的大小。 |
|  void	trimToSize()  | 對此向量的容量進行微調,使其等於向量的當前大小。 |
>
>Vector還定義了很多其他方法,具體可以看:[Java Vector 類](http://www.runoob.com/java/java-vector-class.html)。
  • 哈希表(Hashtable)

Hashtable(確實是小寫的t)是原始的java.util的一部分, 是一個Dictionary具體的實現 。然而,Java 2 重構的Hashtable實現了Map接口,因此,Hashtable現在集成到了集合框架中。它和HashMap類很相似,但是它支持同步(同樣建議不需要同步時使用HashMap)。像HashMap一樣,Hashtable在哈希表中存儲鍵/值對。當使用一個哈希表,要指定用作鍵的對象,以及要鏈接到該鍵的值。然后,該鍵經過哈希處理,所得到的散列碼被用作存儲在該表中值的索引。

Hashtable定義了四個構造方法:

Hashtable();   //默認的初始容量 (11) 和加載因子 (0.75)

Hashtable(int initialCapacity);    //指定初始容量和默認的加載因子 (0.75)

Hashtable(int initialCapacity, float loadFactor);    //

Hashtable(Map m);  //以M中元素為初始化元素,哈希表的容量為M的兩倍。

如果散列表的裝載因子是0.75,那么當散列表的容量被使用了75%時,就會自動將容量增加到原始容量的2倍。通常,默認加載因子(0.75)在時間和空間成本上尋求一種折中,裝載因子過高雖然減少了空間開銷,但同時也增加了查找某個條目的時間。

常用方法:

| 方法 | 描述 |
|-----|------|
|  V put(K key, V value) | 將指定 key 映射到此哈希表中的指定 value。 |
|  V remove(Object key) | 從哈希表中移除該鍵及其相應的值。|
| V	get(Object key) | 返回指定鍵所映射到的值,不包含則返回 null。 |
| void	clear() | 將此哈希表清空,使其不包含任何鍵。 |
|  boolean	containsValue(Object value) | 如果此 Hashtable 將一個或多個鍵映射到此值,則返回 true。 |
|  boolean	isEmpty() | 測試此哈希表是否沒有鍵映射到值。 |
| int size() | 返回此哈希表中的鍵的數量。 |
| void	rehash() | 增加此哈希表的容量並在內部對其進行重組,以便更有效地容納和訪問其元素。 |
>
>Hashtable中還定義了一些其他方法,具體可以看:[Java HashTable 接口](http://www.runoob.com/java/java-hashTable-class.html)。
  • 棧(Stack)

棧是Vector的一個子類,它實現了一個標准的后進先出的棧。堆棧只定義了默認構造函數,用來創建一個空棧。 堆棧除了包括由Vector定義的所有方法,也定義了自己的一些方法,如下:

| 方法 | 描述 |
|------|------|
| boolean empty() | 測試堆棧是否為空。 |
| Object peek( ) | 查看堆棧頂部的對象,但不從堆棧中移除它。 |
| Object pop( ) | 移除堆棧頂部的對象,並作為此函數的值返回該對。 |
| Object push(Object element) | 把項壓入堆棧頂部。 | 
| int search(Object element) | 返回對象在堆棧中的位置,以 1 為基數。 |
>但是Deque **接口**及其實現提供了 LIFO 堆棧操作的更完整和更一致的 set,應該優先使用此 set,而非此類。
>
>注:Java 中 Queue 是接口, Deque 是其子接口,LinkedList 和 PriorityQueue 是其實現類,而 ArrayDeque 是 Deque 接口的實現類。具體方法可以查看:[JDK 1.6 在線中文手冊](http://www.runoob.com/manual/jdk1.6/)。
  • 鏈表(LinkedList)

LinkedList是一個雙端鏈表,存放在結點中的數據都被看作是一個Object對象。由於任何類都是Object類的間接子類,因此,可以把任何一個對象作為鏈表結點中的數據。需要注意的是get()方法返回的類型是Object,要類型轉換回原來的類型。
構造方法:

LinkedList();   //構造一個空列表

LinkedList(Collection<? extends E> c); //包含指定 collection 中的元素

常用方法:

| 方法 | 描述 |
|------|-----|
| boolean add(E e) | 將指定元素添加到此列表的**結尾**。 |
| void add(int index, E element) | 在此列表中指定的位置插入指定的元素。 |
| E remove(int index) | 移除此列表中指定位置處的元素。 |
|  E remove() | 獲取並移除此列表的頭(第一個元素)。 |
| boolean remove(Object o) | 移除首次出現的指定元素,不包含則不作更改。|
| E set(int index, E element) | 將此列表中指定位置的元素替換為指定的元素。 |
|  E get(int index) | 返回此列表中指定位置處的元素。**效率低**,並非隨機訪問。 |
| int indexOf(Object o) | 返回此列表中首次出現的指定元素的索引,不存在則返回-1. |
| boolean contains(Object o) | 至少包含一個指定元素,則返回 true。 |
| int size() | 返回此列表的元素數。 |
| void clear() | 從此列表中移除所有元素。 |
| Object clone() | 返回此 LinkedList 的淺表副本。(這些元素本身沒有復制。) |
| Object[] toArray() | 此方法返回一個新數組,調用者可以隨意修改。 |
>LinkedList也實現了Deque接口,List接口和Queue接口,存在方法支持其用作堆棧、隊列或雙端隊列,這里不做展開,具體方法可以查看:[JDK 1.6 在線中文手冊](http://www.runoob.com/manual/jdk1.6/)。

參考資料


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM