1. 程式人生 > >【10】Java集合:基本體系概述

【10】Java集合:基本體系概述

一、Java集合概述

1.1、什麼是集合?

集合就是將若干用途相同、近似的“資料”結合成一個整體。

1.2、集合的分類

集合從體系上分為三種:Set(集),List(列表),Map(對映)

  1. 列表(List):List集合區分元素的順序,允許包含相同的元素。
  2. 集(Set):Set集合不區分元素的順序,不允許包含相同的元素。
  3. 對映(Map):Map集合儲存的”鍵”-“值”對,“鍵”不能重複,而且一個“鍵”只能對應一個“值”。

Java集合中只能儲存引用資料型別,也就是儲存的是物件的地址,而非物件本身。集合中元素相當於引用型別的變數。

1.3、Java集合類框圖

1.3.1、由Collection介面引申:

這裡寫圖片描述

1.3.2、由Map介面引申:

這裡寫圖片描述

1.3.3、常用的集合類

這裡寫圖片描述

1.3.4、集合全面體系圖

這裡寫圖片描述

說明:類圖中,實線邊框的是實現類,比如ArrayList,LinkedList,HashMap等,折線邊框的是抽象類,比如AbstractCollection,AbstractList,AbstractMap等,而點線邊框的是介面,比如Collection,Iterator,List等。

二、Collection和Iterator介面

2.1、概述

在Collection介面中聲明瞭適用於Java集合(只包括Set和List)的通用方法。因此Set和List物件可以呼叫以上方法,Map物件不可以。

Iterator介面隱藏了底層集合的資料結構,向客戶程式提供了遍歷各種資料集合的統一介面。

如果集合中的元素沒有排序,Iterator遍歷集合中元素的順序是任意的,並不一定與集合中加入元素的順序是一致的。

2.2、Collection介面中的方法:

這裡寫圖片描述

Collection方法舉例:

public class javatest {  
    public static void main(String args[]) { 
        Collection c = new ArrayList();
        c.add("Hello World!");    //新增String型別物件
c.add(new Integer(100)); //新增Integer型別物件 c.add(new Float(2323.45f)); //新增Float型別物件 System.out.println(c.size()); System.out.println(c); } }

三、List介面以及實現類

3.1、List介面

List是Collection的子介面,實現List介面的容器中存放的物件是有順序的,而且可以重複。List容器中存放的物件都有一個整數型的序號,記錄該物件在容器中的位置,可以根據序號來訪問容器中的元素。

JDK提供實現List介面的類有ArrayList、LinkedList等。相關方法如下:

Object get(int index)
Object set(int index,Object obj)
void add(int index,Object obj)
Object remove(int index)
int indexOf(Object obj)
int lastIndexOf(Object obj)

3.2、List介面的實現類-ArrayList

java.util.ArrayList實現了List介面,用於描述長度可變的陣列列表(底層採用陣列實現)。ArrayList允許元素取值為null,提供了一些新增的方法來操作列表的容量的大小。

public ArrayList()
public ArrayList(int initialCapacity)
public void ensureCapacity(int minCapacity)
public void trimToSize()

3.3、List介面的實現類-Vector

java.util.Vector實現了List介面,用於描述長度可變的陣列向量(底層採用陣列實現)。

與ArrayList的區別:Vector是執行緒安全的(同步),用在多執行緒環境中,執行效率慢。ArrayList不是執行緒安全的,用在單執行緒環境中。

Vector類的新增方法:

public Vector()
public Object elementAt(int index)
public void removeElement(int index)
public void insertElement(Object obj,int index)
public boolean removeElement(Object obj)
public void removeAllElements()
public Object toArray()

四、Map介面以及實現類

4.1、Map介面

以該介面為根的集合類,用於儲存“關鍵字”(key)和“值”(value)的元素對,其中每個關鍵字對映到一個值,當需要通過關鍵字實現對值的快速存取時使用。

宣告的抽象方法主要有:查詢方法、修改方法。

兩個主要實現類:

  1. HashTable
  2. HashMap

查詢方法

int size() —— 返回Map中的元素個數

boolean isEmpty() —— 返回Map中是否包含元素,如不包括任何元素,則返回true

boolean containsKey(Object key) —— 判斷給定的引數是否是Map中的一個關鍵字(key)

boolean containsValue(Object val) —— 判斷給定的引數是否是Map中的一個值(value)

Object get(Object key) —— 返回Map中與給定關鍵字相關聯的值(value)

Collection values() —— 返回包含Map中所有值(value)的Collection物件

Set keySet() ——返回包含Map中所有關鍵字(key)的Set物件

Set entrySet() —— 返回包含Map中所有項的Set物件 

修改方法

Object put(Object key, Object val) —— 將給定的關鍵字(key)/值(value)對加入到Map物件中。其中關鍵字(key)必須唯一,否則,新加入的值會取代Map物件中已有的值

void putAll(Map m) —— 將給定的引數Map中的所有項加入到接收者Map物件中

Object remove(Object key) —— 將關鍵字為給定引數的項從Map物件中刪除

void clear() —— 從Map物件中刪除所有的項

4.2、雜湊表

也稱為散列表,是用來儲存群體物件的集合類結構,其兩個常用的類是HashTable及HashMap

雜湊表儲存物件的方式與前面所講的陣列,Vector及ArrayList不同。陣列、Vector及ArrayList中物件的儲存位置是隨機的,即物件本身與其儲存位置之間沒有必然的聯絡。因此查詢一個物件時,只能以某種順序(如順序查詢,二分查詢)與各個元素進行比較,如果陣列或向量中的元素數量很龐大時,查詢的效率必然降低

雜湊表中,物件的儲存位置和物件的關鍵屬性k之間有一個特定的對應關係f,我們稱之為雜湊(Hash)函式。它使每個物件與一個唯一的儲存位置相對應。因而在查詢時,只要根據待查物件的關鍵屬性k,計算f(k)的值即可知其儲存位置

雜湊表相關的一些主要概念:

容量(capacity)—— 雜湊表的容量不是固定的,隨物件的加入,其容量可以自動擴充

關鍵字/鍵(key)—— 每個儲存的物件都需要有一個關鍵字key,key可以是物件本身,也可以是物件的一部分(如物件的某一個屬性)

雜湊碼(hash code)—— 要將物件儲存到HashTable,就需要將其關鍵字key對映到一個整型資料,稱為key的雜湊碼(hash code)

雜湊函式(hash function)——返回物件的雜湊碼

項(item)—— 雜湊表中的每一項都有兩個域:關鍵字域key及值域value(即儲存的物件)。key及value都可以是任意的Object型別的物件,但不能為空(null),HashTable中的所有關鍵字都是唯一的

裝填因子(load factor)—— (表中填入的項數)/(表的容量)

構造方法:

Hashtable( ); // 初始容量為101,最大裝填因子為0.75
Hashtable(int capacity);
Hashtable(int capacity, float maxLoadFactor);

常用方法:

Object put(Object key, Object value) —— 值value以key為其關鍵字加入到雜湊表中,如果此關鍵字在表中不存在,則返回null,否則表中儲存的value;

Object get(Object key) —— 返回關鍵字為key的值value,如果不存在,則返回null;

Object remove(Object key) —— 將鍵/值對從表中去除,並返回從表中去除的值,如果不存在,則返回null;

boolean isEmpty() —— 判斷雜湊表是否為空
boolean containsKey(Object key) —— 判斷給定的關鍵字是否在雜湊表中
boolean contains(Object value) —— 判斷給定的值是否在雜湊表中
boolean containsValue(Object value) —— 判斷給定的值是否在雜湊表中
void clear() —— 將雜湊表清空
Enumeration elements() —— 返回包含值的Enumeration物件
Enumeration keys() —— 返回包含關鍵字的Enumeration物件

HashMap類與HashTable類很相似,只是HashTable類不允許有空的關鍵字,而HashMap類允許。

五、Set介面以及實現類

5.1、Set概述

Set是最簡單的集合,集合中的物件不按照特定的方式排序,並且沒有重複的物件。Set介面主要有兩個實現類:HashSet和TreeSet

Set集合裡多個物件之間沒有明顯的順序,基本與Collection方法相同。只是行為不同(Set不允許包含重複元素)。Set集合不允許重複元素,是因為Set判斷兩個物件相同不是使用==運算子,而是根據equals方法。即兩個物件用equals方法比較返回true

public class TestSet {
    public static void main(String[] args) {
        Set<String> books = new HashSet<String>();
        //新增一個字串物件
        books.add(new String("Struts2權威指南"));
        //再次新增一個字串物件,
        //因為兩個字串物件通過equals方法比較相等,所以新增失敗,返回false
        boolean result = books.add(new String("Struts2權威指南"));
        System.out.println(result);
        //下面輸出看到集合只有一個元素
        System.out.println(books);    
    }
}

程式執行結果:

false 
[Struts2權威指南]

說明:程式中,book集合兩次新增的字串物件明顯不是一個物件(程式通過new關鍵字來建立字串物件),當使用==運算子判斷返回false,使用equals方法比較返回true,所以不能新增到Set集合中,最後只能輸出一個元素。Set介面中的知識,同時也適用於HashSet、TreeSet和EnumSet三個實現類。

5.2、HashSet類

HashSet按Hash演算法來儲存集合的元素,因此具有很好的存取和查詢效能。

HashSet的特點:

(1)HashSet不是同步的,多個執行緒訪問是需要通過程式碼保證同步

(2)集合元素值可以使null。

HashSet集合判斷兩個元素相等的標準是兩個物件通過equals方法比較相等,並且兩個物件的hashCode()方法返回值也相等。例如:

//類A的equals方法總是返回true,但沒有重寫其hashCode()方法  
class A  
{  
    public boolean equals(Object obj)  
    {  
        return true;  
    }  
}  
//類B的hashCode()方法總是返回1,但沒有重寫其equals()方法  
class B  
{  
    public int hashCode()  
    {  
        return 1;  
    }  
}  
//類C的hashCode()方法總是返回2,但沒有重寫其equals()方法  
class C  
{  
    public int hashCode()  
    {  
        return 2;  
    }  
    public boolean equals(Object obj)  
    {  
        return true;  
    }  
}  
public class TestHashSet  
{  
    public static void main(String[] args)   
    {  
        HashSet<Object> books = new HashSet<Object>();  
        //分別向books集合中新增2個A物件,2個B物件,2個C物件  
        books.add(new A());  
        books.add(new A());  
        books.add(new B());  
        books.add(new B());  
        books.add(new C());  
        books.add(new C());  
        System.out.println(books);  
    }  
} 

程式執行結果:

[[email protected]1, [email protected]1, [email protected]2, [email protected], [email protected]9945ce] 

5.3、TreeSet類

TreeSet是SortedSet介面的唯一實現,TreeSet可以確保集合元素處於排序狀態(元素是有序的)。

TreeSet提供的幾個額外方法:

Comparator comparttor(): 返回當前Set使用的Compara投入,或者返回null,表示以自然方式排序。  

Object first():返回集合中的第一個元素。  

Object last():返回集合中的最後一個元素。  

Objiect lower(Object e):返回集合中位於指定元素之前的元素(即小於指定元素的最大元素,參考元素可以不是TreeSet的元素)。  

Object higher(Object e):返回集合中位於指定元素之後的元素(即大於指定元素的最小元素,參考元素可以不需要TreeSet的元素)。  

SortedSet subSet(fromElement, toElement):返回此Set的子集,範圍從fromElement(包含大於等於)到toElement(不包含小於)。  

SortedSet headSet(toElement):返回此Set的子集,由小於toElement的元素組成。  

SortedSet tailSet(fromElement):返回此Set的子集,由大於或等於fromElement的元素組成。

舉個栗子:

public class TestTreeSetCommon  
{  
    public static void main(String[] args)   
    {  
        TreeSet<Integer> nums = new TreeSet<Integer>();  
        //向TreeSet中新增四個Integer物件  
        nums.add(5);  
        nums.add(2);  
        nums.add(10);  
        nums.add(-9);  
        //輸出集合元素,看到集合元素已經處於排序狀態  
        System.out.println(nums);  
        //輸出集合裡的第一個元素  
        System.out.println(nums.first());  
        //輸出集合裡的最後一個元素  
        System.out.println(nums.last());  
        //返回小於4的子集,不包含4  
        System.out.println(nums.headSet(4));  
        //返回大於5的子集,如果Set中包含5,子集中還包含5  
        System.out.println(nums.tailSet(5));  
        //返回大於等於-3,小於4的子集。  
        System.out.println(nums.subSet(-3 , 4));  
    }  
} 

輸入結果:

[-9, 2, 5, 10]
-9
10
[-9, 2]
[5, 10]
[2]

說明:由執行結果可以看出,TreeSet並不是根據元素的插入順序進行排序,而是根據元素實際值來進行排序。TreeSet採用紅黑樹的資料結構對元素進行排序的。