Java容器類包含List、ArrayList、Vector及map、HashTable、HashMap、Hashset
ArrayList和HashMap是異步的,Vector和HashTable是同步的,所以Vector和HashTable是線程安全的,而 ArrayList和HashMap並不是線程安全的。因為同步需要花費機器時間,所以Vector和HashTable的執行效率要低於 ArrayList和HashMap。
由Collection接口派生的兩個接口是List和Set。
List是有序、重復的集合,set是無需不可重復的集合。
Java中的“STL”可以從C++中進行衍生理解,Java擁有了C++的STL功能,這些功能類被封裝在java.util包內,以下簡稱這些類的統稱為J-STL。
util定義了如下接口,J-STL主要實現了以下幾個接口——斜體字表示
Collection (Java 2)
List (Java 2)
Observer
Comparator (Java 2)
ListIterator (Java 2)
Set (Java 2)
Enumeration Map (Java 2)
SortedMap (Java 2)
EventListener
Map.Entry (Java 2)
SortedSet (Java 2)
Iterator (Java 2)
我們所使用的J-STL類都是這些接口的某個實現。下面是簡單的部分介紹。
Collection接口
Collection 能使你操作對象組,它位於類集層次結構的頂層。Collection接口是構造類集框架的基礎。它聲明所有類集都將擁有的核心方法。
一個類集不能直接存儲類型int,char,double等的值,如果要使用這些類型,則使用對象,比如new Integer(1)。
常用的使用方法如下:
boolean add(Object obj) 將obj加入到調用類集中。如果obj被加入到類集中了,則返回true;如果obj已經是類集中的一個成員或類集不能被復制時,則返回false
boolean addAll(Collection c) 將c中的所有元素都加入到調用類集中,如果操作成功(也就是說元素被加入了),則返回true;否則返回false
void clear( ) 從調用類集中刪除所有元素
boolean contains(Object obj) 如果obj是調用類集的一個元素,則返回true,否則,返回false
boolean containsAll(Collection c) 如果調用類集包含了c中的所有元素,則返回true;否則,返回false
boolean equals(Object obj) 如果調用類集與obj相等,則返回true;否則返回false
int hashCode( ) 返回調用類集的散列碼
boolean isEmpty( ) 如果調用類集是空的,則返回true;否則返回false
Iterator iterator( ) 返回調用類集的迭代程序
Boolean remove(Object obj) 從調用類集中刪除obj的一個實例。如果這個元素被刪除了,則返回true;否則返回false
Boolean removeAll(Collection c) 從調用類集中刪除c的所有元素。如果類集被改變了(也就是說元素被刪除了),則返回true;否則返回false
Boolean retainAll(Collection c) 刪除調用類集中除了包含在c中的元素之外的全部元素。如果類集被改變了(也就是說元素被刪除了),則返回true,否則返回false
int size( ) 返回調用類集中元素的個數
List接口
List接口相當於鏈表,無序、可重復。
ArrayList類
ArrayList類擴展AbstractList並執行List接口。ArrayList支持可隨需要而增長的動態數
組。在Java中,標准數組是定長的。在數組創建之后,它們不能被加長或縮短,這也就意
味着你必須事先知道數組可以容納多少元素。但是,你直到運行時才能知道需要多大的數
組。為了解決這個問題,類集框架定義了ArrayList。本質上,ArrayList是對象引用的一個
變長數組。也就是說,ArrayList能夠動態地增加或減小其大小。數組列表以一個原始大小
被創建。當超過了它的大小,類集自動增大。當對象被刪除后,數組就可以縮小。
Vector類
Vector實現動態數組。這與ArrayList相似,但兩者不同的是:Vector是同步的,並且它
包含了許多不屬於類集框架的從以前版本遺留下來的方法。隨着Java 2的公布,Vector被重
新設計來擴展AbstractList和實現List接口。如果沒有指定增量,在每個分配周期,矢量的大小增一倍。
Stack類
Stack是Vector的一個子類,它實現標准的后進先出堆棧
LinkedList類
LinkedList類擴展AbstractSequentialList並執行List接口。它提供了一個鏈接列表數據結
構。
顯然要理解ArrayList和LinkedList這兩種數據結構,可以類比到鏈表和數組的異同。
前者插入到中間的元素對后面的元素造成了移位,效率低,而后者不需要。例子:
private static void testArrayListandLinkedList(){
long start = System.currentTimeMillis();
List<String> list1 = new ArrayList<String>();
for(int i=0;i<10000;i++){
list1.add(0,"hello");
}
long end = System.currentTimeMillis();
System.out.println("start:"+ start + " end:"+end+" time use :"+ (end-start)+"ms");
start = System.currentTimeMillis();
List<String> list2 = new LinkedList<String>();
for(int i=0;i<10000;i++){
list2.add(0,"hello");
}
end = System.currentTimeMillis();
System.out.println("start:"+ start + " end:"+end+" time use :"+ (end-start)+"ms");
}
同樣都插入到第一個元素,LinkedList的效率高的多:
start:1358144834832 end:1358144834874 time use :42ms
start:1358144834875 end:1358144834877 time use :2ms
Set接口
Set接口相當於集合,無序、不可重復。
SortedSet接口相當於有序的集合,有序、不可重復。SortedSet接口擴展了Set並說明了按升序排列的集合的特性。
J-STL迭代器
1. 通過調用類集的iterator( )方法獲得對類集頭的迭代函數。
2. 建立一個調用hasNext( )方法的循環,只要hasNext( )返回true,就進行循環迭代。
3. 在循環內部,通過調用next( )方法來得到每一個元素。
boolean hasNext( ) 如果存在更多的元素,則返回true,否則返回false
Object next( ) 返回下一個元素。如果沒有下一個元素,則引發NoSuchElementException異常
void remove( ) 刪除當前元素,如果試圖在調用next( )方法之后,調用remove( )方法,則引發IllegalStateException異常
void add(Object obj) 將obj插入列表中的一個元素之前,該元素在下一次調用next( )方法時,被返回
boolean hasNext( ) 如果存在下一個元素,則返回true;否則返回false
boolean hasPrevious( ) 如果存在前一個元素,則返回true;否則返回false
Object next( ) 返回下一個元素,如果不存在下一個元素,則引發一個NoSuchElementException異常
int nextIndex( ) 返回下一個元素的下標,如果不存在下一個元素,則返回列表的大小
Object previous( ) 返回前一個元素,如果前一個元素不存在,則引發一個NoSuchElementException異常
int previousIndex( ) 返回前一個元素的下標,如果前一個元素不存在,則返回-1
void remove( ) 從列表中刪除當前元素。如果remove( )方法在next( )方法或previous( )方法調用之前被調用,則引發一個IllegalStateException異常
void set(Object obj) 將obj賦給當前元素。這是上一次調用next( )方法或previous( )方法最后返回的元素
和C++STL有一個很明顯的不同,J-STL不用++和--來移動,而是用next和previous。
Iterator it = l.iterator(); // 獲得一個迭代子
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
Map接口
Map接口
映射循環使用兩個基本操作:get( )和put( )。使用put( )方法可以將一個指定了關鍵字和
值的值加入映射。為了得到值,可以通過將關鍵字作為參數來調用get( )方法。調用返回該
值。正如前面談到的,映射不是類集,但可以獲得映射的類集“視圖”。為了實現這種功
能,可以使用entrySet( )方法,它返回一個包含了映射中元素的集合(Set)。為了得到關鍵
字的類集“視圖”,可以使用keySet( )方法。為了得到值的類集“視圖”,可以使用values( )
方法。類集“視圖”是將映射集成到類集框架內的手段。
SortedMap接口
SortedMap接口擴展了Map,它確保了各項按關鍵字升序排序。由SortedMap說明的方法總結在表15-7中。當調用映射中沒有的項時,其中的幾種方法引發一個NoSuchElementException異常。當對象與映射中的元素不兼容時,則引發一個ClassCastException異常。當試圖使用映射不允許使用的null對象時,則引發一個NullPointerException異常。
字典(Dictionary)是一個表示關鍵字/值存儲庫的抽象類,同時它的操作也很像映射(Map),散列表(Hashtable)是原始java.util中的一部分同時也是Dictionary的一個具體實現。
TreeMap 類
TreeMap類通過使用樹實現Map接口。TreeMap提供了按排序順序存儲關鍵字/值對的有
效手段,同時允許快速檢索。應該注意的是,不像散列映射,樹映射保證它的元素按照關
鍵字升序排序。顯然,TreeMap類顯示出很好的排序優異。
注意對關鍵字進行了排序。然而,在這種情況下,它們用名字而不是用姓進行了排序。
可以通過在創建映射時,指定一個比較函數來改變這種排序
比較函數
TreeSet和TreeMap都按排序順序存儲元素。然而,精確定義采用何種“排序順序”的
是比較函數。通常在默認的情況下,這些類通過使用被Java稱之為“自然順序”的順序存
儲它們的元素,而這種順序通常也是你所需要的(A在B的前面,1在2的前面,等等)。如
果需要用不同的方法對元素進行排序,可以在構造集合或映射時,指定一個Comparator對
象。這樣做為你提供了一種精確控制如何將元素儲存到排序類集和映射中的能力。
Comparator接口定義了兩個方法:compare( )和equals( )。
class MyComp implements Comparator<Object> {
public int compare(Object a, Object b) {
//String aStr, bStr;
//aStr = (String) a;
//bStr = (String) b;
//return bStr.compareTo(aStr);
Integer ai, bi;
ai = (Integer) a;
bi = (Integer) b;
return bi.compareTo(ai);
}
// no need to override equals
}
Map<Integer, String> treemap = new TreeMap<Integer, String>(new MyComp());
HashMap 類
HashMap類使用散列表實現Map接口。這允許一些基本操作如get( )和put( )的運行時間
保持恆定,即便對大型集合,也是這樣的。