標籤:常用類 header one 精確 容量 int treemap style family
Collection介面
- Collection是最基本的集合介面,一個Collection代表一組Object,即Collection的元素(Elements)。
- 所有實現Collection介面的類都必須提供兩個標準的建構函式:無參數的建構函式用於建立一個空的Collection,有一個 Collection參數的建構函式用於建立一個新的Collection,這個新的Collection與傳入的Collection有相同的元素。後 一個建構函式允許使用者複製一個Collection。
- 如何遍曆Collection中的每一個元素?不論Collection的實際類型如何,它都支援一個iterator()的方法,該方法返回一個迭代器,使用該迭代器即可遍曆訪問Collection中每一個元素,通過Iterator的遍曆是無序的。
典型的用法如下:
Iterator it = collection.iterator(); // 獲得一個迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一個元素
}
List介面
- List是有序的Collection,使用此介面能夠精確的控制每個元素插入的位置。使用者能夠使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。
- 除了具有Collection介面必備的iterator()方法外,List還提供一個listIterator()方法,返回一個 ListIterator介面,和標準的Iterator介面相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設定元素, 還能向前或向後遍曆。
- 實現List介面的常用類有LinkedList,ArrayList,Vector和Stack。
LinkedList類
- LinkedList實現了List介面,允許null元素。此外LinkedList提供額外的get,remove,insert方法。這些操作使LinkedList可被用作堆棧(stack),隊列(queue)或雙向隊列(deque)。
- 注意LinkedList沒有同步性。如果多個線程同時訪問一個LinkedList,則必須自己實現訪問同步。另一種解決方案是在建立List時構造一個同步的List:List list = Collections.synchronizedList(new LinkedList(...));
- LinkedList是List介面的一個實作類別
- LinkedList有一些List沒有的特有方法
- LinkedList是一個線性鏈表式結構
- LinkedList的實現
LinkedList<E> list = new LinkedList<E>(); LinkedList<E> list = new LinkedList<E>(Collection c); |
- LinkedList的常見方法
List.add(e); List.add(index,e); List.addFirst(e); List.addLast(e); |
List.get(index); List.getFirst(); List.getLast(); |
ArrayList類
- ArrayList實現了大小可變的數組。它允許所有元素,包括null。ArrayList沒有同步性。
- size,isEmpty,get,set方法已耗用時間為常數。但是add方法開銷為分攤的常數,添加n個元素需要O(n)的時間。其他的方法已耗用時間為線性。
- 每個ArrayList執行個體都有一個容量(Capacity),即用於儲存元素的數組的大小。這個容量可隨著不斷添加新元素而自動增加,但是增長演算法並沒有定義。當需要插入大量元素時,在插入前可以調用ensureCapacity方法來增加ArrayList的容量以提高插入效率。
a) ArrayList實作類別
- ArrayList是List介面的一個實作類別
- ArrayList類是一個線性隊列結構的一個動態數組
- 如何產生一個ArrayList集合
List<泛型> list = new ArrayList<泛型>(); List<泛型> list = new ArrayList<泛型>(Collection c); |
- ArrayList的常見方法
添加方法 list.add(元素); 插入方法 list.add(位置,元素); |
擷取方法 E e = list.get(位置); 擷取集合長度 int len = list.size(); |
**************************************************************************************
遍曆
i
mport java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;import java.util.List;public class TraversalList { //http://www.cnblogs.com/interdrp/p/3663602.html public static void main(String args[]){ List<String> list = new ArrayList<String>( Arrays.asList("tom","cat","Jane","jerry")); //方法1 集合類的通用遍曆方式, 從很早的版本就有, 用迭代器迭代 Iterator it1 = list.iterator(); while(it1.hasNext()){ System.out.println(it1.next()); } //方法2 集合類的通用遍曆方式, 從很早的版本就有, 用迭代器迭代 for(Iterator it2 = list.iterator();it2.hasNext();){ System.out.println(it2.next()); } //方法3 增強型for迴圈遍曆 for(String value:list){ System.out.println(value); } //方法4 一般型for迴圈遍曆 for(int i = 0;i < list.size(); i ++){ System.out.println(list.get(i)); } }}
***************************************************************************************************
Vector類
Vector非常類似ArrayList,但是Vector是同步的。由Vector建立的Iterator,雖然和 ArrayList建立的Iterator是同一介面,但是,因為Vector是同步的,當一個Iterator被建立而且正在被使用,另一個線程改變了 Vector的狀態(例如,添加或刪除了一些元素),這時調用Iterator的方法時將拋出 ConcurrentModificationException,因此必須捕獲該異常。
Stack 類
Stack繼承自Vector,實現一個後進先出的堆棧。Stack提供5個額外的方法使得Vector得以被當作堆棧使用。基本的push和pop 方法,還有peek方法得到棧頂的元素,empty方法測試堆棧是否為空白,search方法檢測一個元素在堆棧中的位置。Stack剛建立後是空棧。
Vector、ArrayList和LinkedList比較
- 1.Vector是線程同步的,所以它也是安全執行緒的,而ArrayList和LinkedList是非安全執行緒的。如果不考慮到線程的安全因素,一般用ArrayList和LinkedList效率比較高。
- 2.ArrayList和Vector是實現了基於動態數組的資料結構,LinkedList基於鏈表的資料結構。
- 3.如果集合中的元素的數目大於目前集合數組的長度時,Vector增長率為目前數組長度的100%,而ArrayList增長率為目前數組長度的50%.如果在集合中使用資料量比較大的資料,用vector有一定的優勢;反之,用ArrayList有優勢。
- 3.如果尋找一個指定位置的資料,Vector和ArrayList使用的時間是相同的,花費時間為O(1),而LinkedList需要遍曆尋找,花費時間為O(i),效率不如前兩者。
- 4.而如果移動、刪除一個指定位置的資料花費的時間為0(n-i)n為總長度,這個時候就應該考慮使用LinkedList,因為它移動一個指定位置的資料所花費的時間為0(1)。
- 5.對於在指定位置插入資料,LinedList比較佔優勢,因為ArrayList要移動資料。
Set介面
- Set是一種不包含重複的元素的Collection,即任意的兩個元素e1和e2都有e1.equals(e2)=false,Set最多有一個null元素。
- 很明顯,Set的建構函式有一個約束條件,傳入的Collection參數不能包含重複的元素。
- 請注意:必須小心操作可變對象(Mutable Object)。如果一個Set中的可變元素改變了自身狀態導致Object.equals(Object)=true將導致一些問題。
**********************************************************************************************************
import java.util.*;
public class TraversalSet { public static void main(String args[]){ List<String> list = new ArrayList<>( Arrays.asList("tom","cat","Jane","jerry")); Set<String> set = new HashSet<>(); set.addAll(list); //方法1 集合類的通用遍曆方式, 從很早的版本就有, 用迭代器迭代 Iterator it1 = set.iterator(); while(it1.hasNext()){ System.out.println(it1.next()); }
//方法2 集合類的通用遍曆方式, 從很早的版本就有, 用迭代器迭代 for(Iterator it2 = set.iterator();it2.hasNext();){ System.out.println(it2.next()); } //方法3 增強型for迴圈遍曆 for(String value: set){ System.out.println(value); } }}
**************************************************************************************************************************************
Map介面
請注意,Map沒有繼承Collection介面,Map提供key到value的映射。一個Map中不能包含相同的key,每個key只能映射一個 value。
Map介面提供3種集合的視圖,Map的內容可以被當作一組key集合,一組value集合,或者一組key-value映射。
*************************************************************************************
遍曆詳情請瀏覽曆史
********************************************************************************************************************************
Hashtable類
- Hashtable繼承Map介面,實現一個key-value映射的雜湊表。任何非空(non-null)的對象都可作為key或者value。
- 添加資料使用put(key, value),取出資料使用get(key),這兩個基本操作的時間開銷為常數。
- Hashtable通過initial capacity和load factor兩個參數調整效能。通常預設的load factor 0.75較好地實現了時間和空間的均衡。增大load factor可以節省空間的但相應的尋找時間將增大,這會影響像get和put這樣的操作。
- 由於作為key的對象將通過計算其散列函數來確定與之對應的value的位置,因此任何作為key的對象都必須實現hashCode和equals方法。hashCode和equals方法繼承自根類Object。
- Hashtable是同步的。
HashMap類
HashMap和Hashtable類似,不同之處在於HashMap是非同步的,並且允許null,即null value和null key。但是將HashMap視為Collection時(values()方法可返回Collection),其迭代子操作時間開銷和HashMap 的容量成比例。因此,如果迭代操作的效能相當重要的話,不要將HashMap的初始化容量設得過高,或者load factor過低。
TreeMap類
- HashMap通過hashcode對其內容進行快速尋找,無序的;而TreeMap中所有的元素都保持著某種固定的順序,有序的。
- 在Map 中插入、刪除和定位元素,HashMap 是最好的選擇。但如果您要按自然順序或自訂順序遍曆鍵,那麼TreeMap會更好。使用HashMap要求添加的鍵類明確定義了hashCode()和 equals()的實現。
- TreeMap沒有調優選項,因為該樹總處於平衡狀態。
WeakHashMap類
WeakHashMap是一種改進的HashMap,它對key實行“弱引用”,如果一個key不再被外部所引用,那麼該key可以被GC回收。
總結
- 如果涉及到堆棧,隊列等操作,應該考慮用List;對於需要快速插入,刪除元素,應該使用LinkedList;如果需要快速隨機訪問元素,應該使用ArrayList。
- 如果程式在單線程環境中,或者訪問僅僅在一個線程中進行,考慮非同步的類,其效率較高;如果多個線程可能同時操作一個類,應該使用同步的類。
- 要特別注意對雜湊表的操作,作為key的對象要正確複寫equals和hashCode方法。
- 使用Map時,尋找、更新、刪除、新增最好使用HashMap或HashTable;對Map進行自然順序或自訂鍵順序遍曆時,最好使用TreeMap;
- 盡量返回介面而非實際的類型,如返回List而非ArrayList,這樣如果以後需要將ArrayList換成LinkedList時,用戶端代碼不用改變。這就是針對抽象編程。
比較常用的有Arraylist linkedlist treemap hashmap四種
Java集合架構