2015-02-21

[轉載] 淺談 Java 中的 Set、List、Map 的區別

轉載自:浅谈Java中的Set、List、Map的区别 - 51CTO.COM

就學習經驗,淺談 Java 中的 Set,List,Map 的區別,對 Java 的集合的理解是想對於陣列:

陣列是大小固定的,並且同一個陣列只能存放類型一樣的數據(基本類型/引用類型),Java 集合可以存儲和操作數目不固定的一組數據。所有的 Java 集合都位於 java.util包中!Java 集合只能存放引用類型的的數據,不能存放基本數據類型。


Java 集合主要分為三種類型:
  • Set(集)
  • List(列表)
  • Map(映射)




Collection 介面 :


Collection 是最基本的集合介面,聲明了適用於 Java 集合(只包括 Set 和 List)的通用方法。Set 和 List 都繼承了 Conllection

Collection 介面的方法:
  • boolean add(Object o)向集合中加入一個物件的引用
  • void clear() 刪除集合中所有的物件,即不再持有這些物件的引用
  • boolean isEmpty() 判斷集合是否為空
  • boolean contains(Object o) 判斷集合中是否持有特定物件的引用
  • Iterartor iterator() 返回一個 Iterator 物件,可以用來遍歷集合中的元素
  • boolean remove(Object o) 從集合中刪除一個物件的引用
  • int size() 返回集合中元素的數目
  • Object[] toArray() 返回一個陣列,該陣列中包括集合中的所有元素

關於:Iterator() 和 toArray() 方法都用於集合的所有的元素,前者返回一個 Iterator 物件,後者返回一個包含集合中所有元素的陣列。

Iterator 介面聲明了如下方法:
  • hasNext() 判斷集合中元素是否遍歷完畢,如果沒有,就返回 true
  • next() 返回下一個元素
  • remove() 從集合中刪除上一個有 next() 方法返回的元素。



Set(集合):


Set 是最簡單的一種集合。集合中的物件不按特定的方式排序,並且沒有重復物件。

Set 介面主要實現了兩個實現類:
  • HashSet 按照哈希算法來存取集合中的物件,存取速度比較快。
  • TreeSet 實現了 SortedSet 介面,能夠對集合中的物件進行排序。

Set 的用法:存放的是物件的引用,沒有重復物件
Set set=new HashSet();  
 
String s1=new String("hello");  
String s2=s1;  
String s3=new String("world");  
 
set.add(s1);  
set.add(s2);  
set.add(s3);  

System.out.println(set.size()); //打印集合中对象的数目 为 2。  

Set 的 add()方法是如何判斷物件是否已經存放在集合中?
boolean isExists=false;  
Iterator iterator=set.iterator();  
 
while(it.hasNext()) {
    String oldStr=it.next();  
    if(newStr.equals(oldStr)){  
        isExists=true;  
    }  
}  



List(列表):


List的特征是其元素以線性方式存儲,集合中可以存放重復物件。

List介面主要實現類包括:
  • ArrayList 代表長度可以改變得陣列。可以對元素進行隨機的訪問,向 ArrayList() 中插入與刪除元素的速度慢。
  • LinkedList 在實現中采用鏈表數據結構。插入和刪除速度快,訪問速度慢。

對於 List 的隨機訪問來說,就是只隨機來檢索位於特定位置的元素。 List 的 get(int index) 方法放回集合中由參數 index 指定的索引位置的物件,下標從“0” 開始。最基本的兩種檢索集合中的所有物件的方法:

1: for 循環和 get()方法:
for(int i=0; i < list.size(); i++){  
    System.out.println(list.get(i));  
}    

2: 使用 迭代器(Iterator):
Iterator it = list.iterator();  
while(it.hashNext){  
    System.out.println(it.next);  
}  



Map(映射):


Map 是一種把鍵物件和值物件映射的集合,它的每一個元素都包含一對鍵物件和值物件。 Map 沒有繼承於 Collection 介面從 Map 集合中檢索元素時,只要給出鍵物件,就會返回對應的值物件。

Map 的常用方法:
  • Object put(Object key, Object value) 向集合中加入元素
  • Object remove(Object key) 刪除與KEY相關的元素
  • void putAll(Map t) 將來自特定映像的所有元素添加給該映像
  • void clear() 從映像中刪除所有映射
  • boolean containsKey(Object key) 判斷映像中是否存在關鍵字 key
  • boolean containsValue(Object value) 判斷映像中是否存在值 value
  • int size() 返回當前映像中映射的數量
  • boolean isEmpty() 判斷映像中是否有任何映射
  • Object get(Object key) 獲得與關鍵字 key 相關的值 。Map 集合中的鍵物件不允許重復,也就說任意兩個鍵物件通過 equals() 方法比較的結果都是 false,但是可以將任意多個鍵獨享映射到同一個值物件上。



Collections 集合實用類:

Collections 提供了供 Java 集合實用的靜態方法。



List 的功能方法


實際上有兩種 List:
一種是基本的 ArrayList,其優點在於隨機訪問元素,另一種是更強大的 LinkedList,它並不是為快速隨機訪問設計的,而是具有一套更通用的方法。
List
次序是 List 最重要的特點:它保證維護元素特定的順序。List 為 Collection 添加了許多方法,使得能夠向 List 中間插入與移除元素(這只推薦 LinkedList 使用)。一個 List 可以生成 ListIterator,使用它可以從兩個方向遍歷 List,也可以從 List 中間插入和移除元 素。
ArrayList
由陣列實現的 List。允許對元素進行快速隨機訪問,但是向 List 中間插入與移除元素的速度很慢。ListIterator 只應該用來由後向前遍歷 ArrayList,而不是用來插入和移除元素。因為那比 LinkedList 開銷要大很多。
LinkedList
對順序訪問進行了優化,向 List 中間插入與刪除的開銷並不大。隨機訪問則相對較慢(使用 ArrayList 代替)。還具有下列方 法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 這些方法 (沒有在任何介面或基類中定義過)使得 LinkedList 可以當作堆棧、隊列和雙向隊列使用。



Set的功能方法


Set 具有與 Collection 完全一樣的介面,因此沒有任何額外的功能,不像前面有兩個不同的 List。實際上 Set 就是 Collection,只是行為不同(這是繼承與多態思想的典型應用:表現不同的行為)。Set 不保存重復的元素(至於如何判斷元素相同則較為負責)

Set:存入 Set 的每個元素都必須是唯一的,因為 Set 不保存重復元素。加入 Set 的元素必須定義 equals() 方法以確保物件的唯一性。Set 與 Collection 有完全一樣的介面。Set 介面不保證維護元素的次序。
HashSet
為快速查找設計的 Set。存入 HashSet 的物件必須定義 hashCode()。
TreeSet
保存次序的 Set,底層為樹結構。使用它可以從 Set 中提取有序的序列。
LinkedHashSet
具有 HashSet 的查詢速度,且內部使用鏈表維護元素的順序(插入的次序)。於是在使用迭代器遍歷 Set 時,結果會按元素插入的次序顯示。



Map的功能方法


方法 put(Object key, Object value) 添加一個“值”(想要得東西)和與“值”相關聯的“鍵”(key)(使用它來查找)。方法 get(Object key) 返回與給定“鍵”相關聯的“值”。可以用 containsKey() 和 containsValue() 測試 Map 中是否包含某個“鍵”或“值”。 標准的 Java 類庫中包含了幾種不同的 Map:HashMap, TreeMap, LinkedHashMap, WeakHashMap, IdentityHashMap。它們都有同樣的基本介面Map,但是行為、效率、排序策略、保存物件的生命周期和判定“鍵”等價的策略等各不相同。

執行效率是 Map 的一個大問題。看看 get() 要做哪些事,就會明白為什麼在 ArrayList 中搜索“鍵”是相當慢的。而這正是 HashMap 提高速度的地方。HashMap 使用了特殊的值,稱為“散列碼”(hash code),來取代對鍵的緩慢搜索。“散列碼”是“相對唯一”用以代表物件的 int 值,它是通過將該物件的某些信息進行轉換而生成的。所有 Java 物件都 能產生散列碼,因為 hashCode() 是定義在基類 Object 中的方法。
HashMap
Map 基於散列表的實現。插入和查詢“鍵值對”的開銷是固定的。可以通過構造器設置容量 capacity 和負載因子 load factor,以調整容器的性能。HashMap 就是使用物件的 hashCode() 進行快速查詢的。此方法能夠顯著提高性能。
LinkedHashMap
類似於 HashMap,但是迭代遍歷它時,取得“鍵值對”的順序是其插入次序,或者是最近最少使用(LRU)的次序。只比 HashMap 慢一點。而在迭代訪問時發而更快,因為它使用鏈表維護內部次序。
TreeMap
基於紅黑樹數據結構的實現。查看“鍵”或“鍵值對”時,它們會被排序(次序由 Comparabel 或 Comparator 決定)。TreeMap 的特點在 於,你得到的結果是經過排序的。TreeMap 是唯一的帶有 subMap() 方法的 Map,它可以返回一個子樹。
WeakHashMao
弱鍵(weak key)Map,Map 中使用的物件也被允許釋放: 這是為解決特殊問題設計的。如果沒有 map 之外的引用指向某個“鍵”,則此“鍵”可以被垃圾收集器回收。
IdentifyHashMap
使用 == 代替 equals() 對“鍵”作比較的 hash map。專為解決特殊問題而設計。



總結:


Java 集合的基本用法,都歸納了,上面這些是平常最常用的 Java 集合,具體的其他的,還要參考JDK幫助文檔了,呵呵 關於 Map的應用,還有很多,具體就是這個,Collections 提供了很多 List / Map 實用的方法,對平常開發非常有用。

List 按物件進入的順序保存物件,不做排序或編輯操作。Set 對每個物件只接受一次,並使用自己內部的排序方法(通常,你只關心某個元素是否屬於 Set,而不關心它的順序,否則應該使用 List)。Map 同樣對每個元素保存一份,但這是基於"key"的,Map 也有內置的排序,因而不關心元素添加的順序。如果添加元素的順序對你很重要,應該使用 LinkedHashSet 或者 LinkedHashMap.

3 則留言:

  1. Javascript 有map list嗎

    回覆刪除
  2. Javascript 有map list嗎

    回覆刪除
  3. var map = {};

    map['a'] = '1';
    map['b'] = '2';

    接著用 for in 或 Object.keys(obj) 或 jQuery.each 就可以疊代,當然這是不包證順序的

    HTML5 還有 Map object 可以用

    回覆刪除

你好!歡迎你在我的 Blog 上留下你寶貴的意見。