Google Prettify

2014-09-03

簡介Java Collection Framework

Java Collection Framework 通制是Java 入門比較困惑的一塊地方。這篇文章主要是對Java Collection的這個部份做一個解釋,讓剛入門的讀者可以對這塊可以比較快上手。

最基本上Collection  Framework就如圖所示:

Java Collection Framework常用interface
首先,什麼是Collection ? Collection 是一種資料結構,表示有很多東西在一塊

就這樣嗎?

就這樣。

多麼抽像的敘述啊。沒錯,如果光是這樣的敘述,確實是太「抽像」,而這也是物件導向的一個特色─抽像化。在Collection Framework裡,Collection 這個類別是位於相當高層的類別,除了「很多東西在一塊」這樣的描述可以定義Collection外,其他的描述或定義都交由子類別去決定。不過別忘了,在Java裡,抽像類別是無法產生實體物件(instance),必需要有實作(implement)的類別才可以產生 instance,所以我們在使用的時候,不會直接使用這些 抽像化的類別,而是使用相對應的實作類別來產生instance。

(PS: 其實Collection不是一個抽像類別(abstract class) 或是 class,而是一個 interface,不過在這裡先暫時不用區分的那麼清楚,總而言之,他就是一個定義不是那麼清楚的東西)。

為了介紹常用的一些實作類別,先舉一個情境。比方說我有一個叫做「職業」的Collection,裡面存放著各式各樣的職業:



以程式碼來說,就是這樣:
package taichitech.helloworld.jse;
import java.util.HashSet;
public class CollectionTest {
 public static void main(String[] args) {
  Set collection = new HashSet();
  collection.add("警察");
  collection.add("醫生");
  collection.add("公務員");
  collection.add("謢士");
  collection.add("工人");
  System.out.println(collection);
 }
}
執行結果:
[警察, 公務員, 工人, 醫生, 謢士]
這段程式碼中,有許多部份會在後面再詳加說明。

我們首先要討論的是繼承Collection的三個 Interface: SetListMap。這三種Interface,可以視為是3種資料結構,也各有其不同的特性:

第一個interface是Set,是最簡單的Collection資料結構,就是集合。Set 唯一的限制是不允許重覆的物件存在。實務上常利用這個特性,來過濾重覆的資料。

Set中不允許存放相同的物件
Set 常用的實作主要有3個:
  • LinkedHashSet
    保證裡面元素存放的順序與新增時相同。最適合拿來存放由資料庫中撈取的資料集。
  • HashSet
    讀取特快,但不保證存放元素的順序。我在上一個程式範例中所使用的 Set 的instance就是HashSet,可以看到執行結果的順序與當初存放的順序是不一樣的。
  • TreeSet
    依物件大小來決定集合裡面的順序。所以存放於TreeSet中元素必需是(實作) Comparable 的物件。有時候當從自料庫中撈取的資料必需自行排序時,就會用到。
第二個要談繼承Collection的interface是List。

List比Set多了一個索引編號,而且也允許重覆:

List資料結構由0-based 的數字來決定位置,同時也允許重覆的物件存在在相同一個collection中

程式碼大概是:
public class CollectionTest {
 public static void main(String[] args) {
  List collection = new ArrayList();
  collection.add("警察");
  collection.add("醫生");
  collection.add("醫生");
  collection.add("護士");
  collection.add("工人");
  System.out.println(collection);
  System.out.println("第一個醫生的位置是:" + (collection.indexOf("醫生")));
 }
}
執行結果大概是:
[警察, 醫生, 醫生, 護士, 工人]
第一個醫生的位置是:1
由於List比Set多了一個索引編號(index),這點也成了要使用List或是Set的一個主要判斷因素。(另一個是資料是否 會/需要 重覆)。例如如果你想取得醫生後面第三個職業是什麼,就可以直接使用索引的方式去取得,好過跑3圈迴圈─好吧,也許3圈不算什麼,如果是30000圈就應該有點差了吧。
System.out.println("第一個醫生後的第30000個職業是:"+ (collection.get(collection.indexOf("醫生") + 30000)));

一般常見的List實作只有 ArrayList,如範例所示。當然因應其他需求,也是還有其他的實作可以用,如LinedList、Stack。

繼承Collection的第三種 interface 是 Map

Map的資料結構比較特殊,是一種所謂的「key-value」的資料結構。Key-Value可以把他想像成跟List一樣,也是有一個索引在那裡(就是Key),只是在List中這個索引是數字,而且是從0開始,在Map中這個索引改成物件。通常來說,這個索引是String,不過例外的情況其實也不少,有些情況下,甚至會拿另外一個物件來當做key。(其實String本身也就是一種物件)。



public class CollectionTest {

 public static void main(String[] args) {
  Map collection = new HashMap();
  collection.put("police", "警察");
  collection.put("doctor1", "醫生");
  collection.put("doctor2", "醫生");
  collection.put("worker", "工人");
  collection.put("official", "公務員");
  System.out.println(collection);
  System.out.println("Worker的職業是:" + collection.get("worker"));
 }
}

執行結果大概是:
{doctor2=醫生, doctor1=醫生, police=警察, nurse=護士, worker=工人}
Worker的職業是:工人
Map有幾個特性需要知道:
  1. key不能重覆 
  2. 沒了… XD 
只有key不能重覆的意思表示value是可以重覆的,甚至在「某些」實作上也可以放null,但是只能有一個,因為2個null也算重覆了。
常使用的Map實作比List多:
  • HashMap
    最基礎的Map。一般也比較常用這個。如同一般的Hash系列,HashMap中元素的存放順序也是隨機的。(如前面的程式範例)。
  • TreeMap
    Key值可以依照指定的比較方式來進行排序。所以存放於key值的物件必需要是comparable 的。通常這種可以即時排序的資料結構,異動速度都是會打折扣的。TreeMap也不例外。
  • LinkedHashMap
    與HashMap相同,但保證元素存放的順序與放入的順序相同。
[收尾]

這篇文章對Java Collection Framework做了一點介紹,各位可以在適當的時機使用不同的實作,來達成目的:

  • 需要手動對資料庫或是外部資料源進行排序的時候,可以使用Tree系列。搭配Map,更可以對物件的特定屬性做排序。例如以身份證字號為key值,要排序的物件為value,放入TreeMap即可。
  • 需要對集合進行批次處理時,可以使用Set─無論是HashSet或是LinkedHashSet。如果在處理時有需要考慮順序,就絕對不能使用HashSet。
  • 如果在處理時,需要使用關鍵字、代碼、編號等來取得資料或時,可以考慮使用Map。


沒有留言 :

您或許對這些有興趣

Related Posts with Thumbnails

最後

謝謝您的閱讀,希望您可以有豐富的收獲。