2013年9月10日 星期二

Collections And Generic



   作者: 許裕永

當我們有大量資料要管理時,以前想到的會是陣列,從現在開始,不要再想它了。它只適合用來處少量資料,而且是變動性不大的少量資料。舉個最簡單的例子:把 陣列長度6的陣列物件中的第4個陣列元素刪掉。你程式碼要怎麼寫?辛辛苦苦寫好了以後,再把某一個值做為此陣列物件的第二個陣列元素值,昏倒!
從這裏我們可以看到,陣列的元素要變動,就是一個又一個的迴圈,把元素值移過來又移過去,陣列元素越多就寫得越累。萬一是多維陣列,那就真的只有祝你幸福了。
集合及泛型,就是方便我們管理大量資料的工具。這裏所謂的集合,指的是java‧util中,與集合相關的類別。這些與集合相關的類別建構的物件,可以用 來管理其他的物件,那些被集合物件管理的物件(新增至集合物件中的物件)我們後續便稱之為「元素」。而不同的集合類別所建構的物件,其管埋元素的模式自然 各有特色。認證時,測驗的重點便是這些集合類別的差異性,並不會有大型的考題,請熟記各個不同界面的特色,以及實作相同界面的各個類別的差異性。
1. Set Interface
Set這個界面的特色,便是對集合中的物件沒有建立識別系統。因為沒有識別系統,所以集合中的元素也就不能重複;相對的也就沒有辦法取得集合中某一個指定的元素。
Set中比較重要的方法有五個:
boolean add(Object o)
新增元素至集合中。
void clear()
清除集合中所有元素。
Iterator iterator()
取得導覽物件。
boolean remove(Object o)
刪除指定元素。
int size()
取得集合中的元素個數
接下來介紹的三個類別都實作Set這個界面,自然均擁上述之特色及方法成貝。不過它們對集合內元素的排列方式卻大不相同。
1-1 HashSet
對於集合物件中的元素是以預設方式排列,也就是不會依照加入的順序排列。
例一:
import java.util.*;
public class SetTest{
 public static void main(String[] args){
  HashSet set=new HashSet();
  set.add(new String("Java"));
  set.add(new Date());
  set.add(new Integer(5));
  set.add(null);
  set.add(new String("Java"));
  Iterator i=set.iterator();
  while(i.hasNext()){
   System.out.println(i.next());
  }
 }
}
列印結果:null Java Fri Jan 05 02:16:06 CST 2007 5
示範主題:1、用add()新增元素至集合物件之中。2、可以新增null,但只能一個,因為值不能重複。3、equals()比對值為true的元素只能儲存一個。4、導覽物件的使用。5、排列的順序和新增順序無關。
 
例二:
import java.util.*;
public class SetTest{
 public static void main(String[] args){
  HashSet set=new HashSet();
  set.add(new A());
  set.add(new A());
  set.add(new A());
  set.add(new A());
  set.add(new A());
  System.out.println(set.size());
 }
}
class A{
 public boolean equals(Object o){
  return true;
 }
 public int hashCode(){
  return 5;
 }
}
列印結果:1。
示範主題:若開發類別時,equals及hashCode開發不當,將對此類別建構的物件帶來運算時的困擾(不只是在集合物件之中,還有其他狀況)。
 
1-2 LinkedHashSet
集合物件中的元素,是以新增的順序排列,也就是先進先出。
例一:
import java.util.*;
public class SetTest{
 public static void main(String[] args){
  LinkedHashSet set=new LinkedHashSet();
  set.add(new String("Java"));
  set.add(new Date());
  set.add(new Integer(5));
  set.add(null);
  set.add(new String("Java"));
  for(Object o:set)
   System.out.println(o);
 }
}
列印結果:Java Fri Jan 05 14:18:17 CST 2007 5 null
示範主題:1、集合物件中的元素是以新增的順序排列。2、用for each的寫法可以取代使用iterator物件。3、從任何型別的集合物件中取出元素時,各元素的型別均為Object。
 
1-3 TreeSet
集合物件中的元素會從小到大自動排序。
例一:
import java.util.*;
public class SetTest{
 public static void main(String[] args){
  TreeSet set=new TreeSet();
  set.add(new String("Java"));
  set.add(new Date());
  set.add(new Integer(5));
  set.add(null);
  set.add(new String("Java"));
  for(Object o:set)
   System.out.println(o);
 }
}
執行結果:編譯正確,但執行時出現錯誤訊息:
java.lang.ClassCastException: java.lang.String

示範主題:1、因為本集合物件有自動排序功能,若集合物件中的元素無法比較大小時,便會產生錯誤訊息。2、null亦會造成執行時期錯誤(因為無法比較大小)。
 
例二:
import java.util.*;
public class SetTest{
 public static void main(String[] args){
  TreeSet set=new TreeSet();
  set.add(new String("Java"));
  set.add(new String("JAva"));
  set.add(new String("JaVa"));
  set.add(new String("JavA"));
  set.add(new String("java"));
  for(Object o:set)
   System.out.println(o);
 }
}
列印結果:JAva JaVa JavA Java java
示範主題:字串排序比對方式:1、以字元碼比對。2、由左向右逐字元比對。
 
2. List Interface
List這個界面的特色,便是會對集合物件中的每個元素給予一個序號以資識別。如同陣列一般序號從0開始,到元素個數減1;和陣列不同的是,你可以任意的新增或刪除任何一個元素,而不必去擔必序號的問題,List集合物件會幫你搞定。
因為有了識別系統,不像Set是以元素本身的值為識別,所以List中是可以置入equals()比對值為true的元素的。
List和Set是同一個父界面(Collection),List中的方法,除了上述Set中所列出的五個之外(remove有兩個),另外還有一些重要方法:
void add(int index, E element)
將元素新增至指定序號的位置,原先集合物件中的元素會逐一往後退一個序號。
E get(int index)
取得指定序號的元素。
int indexOf(Object o)
查詢某個物件在本集合物件中的序號,若不存在則運算結果為-1。
E set(int index, E element)
設定參數物件為指定序號位置的元素,此序號原先就已經存放的元素,將被參數物件取代。
Object[] toArray()
將本集合物件轉換為Object型別的一維陣列物件。
 
2-1 LinkedList
集合物件中的元素,會以新增的順序或指定的位置排列。
例一:
import java.util.*;
public class ListTest{
 public static void main(String[] args){
  LinkedList list=new LinkedList();
  list.add(new String("Java"));
  list.add(new Integer(8));
  list.add(new Double(3.0));
  list.add(1,new String("SCJP"));
  //list.add(8,new String("Over"));
  list.set(3,new String("Set"));
  for(int a=0;a<list.size();a++){
   System.out.println(list.get(a));
  }
 }
}
列印結果:Java SCJP 8 Set
示範主題:1、若未指定序號,元素以新增順序排列。2、指定的序號若超出List物件大小,將會造成執行時期錯誤。3、set()會取代原有元素。4、可以用序號逐一取得集合物件中之元素。
 
2-2 ArrayList
ArrayList集合物件的基本功能,和LinkedList大同小異,差別在於內部運算模式,而運算模式對我們而言並不重要。我只需要知道:LinkedList的搜尋效率較高;ArrayList的新增及刪除效率較好。實務使用時,按需求使用適當的類別就可以了。
 
2-3 Vector
Vector提供的功能和上述兩個類別也是大同小異,而其採用的運算模式和ArrayList是一樣的。它最大的特色是:支援執行緒同步化,也就是這個類 別的所有方法均宣告為synchronized。在需要注意執行緒安全的程式之中(如網路伺服器程式)建構List集合物件,就非它不可了。
 
3. Queue Interface
Queue是一個很特殊的界面,它最大的特色就是提供了取得元素後順便刪除該元素的方法。可以讓我們在先進先出、即用即丟的用途上,得到最高的效率。
Queue和Set是同一個父界面(Collection),所以Set中介紹的五個方法,Queue也都有,另外還有下列重點方法:
E element() 
取得集合物件中的第一個元素,但不刪除。 
E peek() 
取得集合物件中的第一個元素,但不刪除。如果集合物件中沒有任何元素,則運算結果為null。
E remove() 
取得集合物件中的第一個元素,並刪除此元素。
 E poll() 
取得集合物件中的第一個元素,並刪除此元素。如果集合物件中沒有任何元素,則運算結果為null。
boolean offer(E o) 
將參數物件新增至集合物件中。
 
3-1 LinkedList
LinkedList除了實作List界面之外,也實作了Queue界面。使用者可以依照程式需求自行決定要呼叫的方法,當然這也是測驗的重點。
例一:
import java.util.*;
public class QueueTest{
 public static void main(String[] args){
  LinkedList queue=new LinkedList();
  queue.offer(new String("Java"));
  queue.offer(new Double(3.5));
  queue.offer(new Date(107,0,1));
  while(queue.size()>0)
  System.out.println(queue.poll());
  System.out.println(queue.peek());
 }
}
列印結果:Java 3.5 Mon Jan 01 00:00:00 CST 2007 null
示範主題:1、LinkedList類別建構的物件,可以執行List的方法,也可以執行Queue的方法。2、因為是執行poll()來取得集合物件中 的元素,元素取得後會立刻刪除,所以不能用for each,也不適合用一般的for。3、迴圈結束之後,集合物件中已經沒有元素。
 
3-2 PriorityQueue
這個類別提供了,List的所有類別所做不到的功能:自動排序。而且它的排序方式還可以自訂。雖然有一點複雜,還是值得一提。
建構方法:PriorityQueue(int initialCapacity, Comparator<? super E> comparator)
此類別有多個建構方法,但只有這一個可以自訂排序方式。其他建構方法建構的物件以預設方式排序(同TreeSet)。
initialCapacity:這個參數只要是大於0的數字即可,用來設定集合物件的初始化容量,預設值是11。但事實上元素個數超過這個初始化容量的設定值並沒有關係。
comparator:這是一個Comparator物件。這個物件中設計了排序的準則,PriorityQueue集合物件就是用Comparator 物件來執行自動排序。Comparator是一個界面,裏面有兩個方法,一個叫compare,另一個叫equals,自訂的排序準則便寫在 compare之中,這個方法的運算結果分為負值、0及正值,分別代表小於、等於及大於的關係。
例一:
import java.util.*;
public class QueueTest{
 public static void main(String[] args){
  PriorityQueue queue=new PriorityQueue(2,new Comparator(){
   public int compare(Object o1,Object o2){
    if(o1.hashCode()>o2.hashCode()){
     return 1;
    }else if(o1.hashCode()<o2.hashCode()){
     return -1;
    }
    return 0;
   }
  });
  queue.offer(new String("Java"));
  queue.offer(new Double(3.5));
  queue.offer(new Date(107,0,1));
  while(queue.size()>0)
   System.out.println(queue.poll());
  System.out.println(queue.peek());
 }
}
檔案重點:1、用匿名類別寫法來建構Comparator物件。2、overriding compare時使用的參數列中,可以使用任意型別,不一定要 Object。但是用Obejct的好處是任何物件都可以相互比較,不至於因為物件型別不一而產生錯誤。3、以物件hashCode之值為比較的準則。
列印結果:Mon Jan 01 00:00:00 CST 2007 Java 3.5 null
示範主題:集合物件依自訂的排序準則來排序,不會因為元素型別不一樣無法比較而顯示錯誤訊息。
 
4. Map Interface
Map這個界面的特色,是可以讓我們指定一個物件做為元素的識別代號,來取代List界面用序號做為元素的代號。而做為識別代號的物件我們稱之為key,它必須是唯一的;做為元素的我們稱之為Value,至於元素的值是可以重複的。
Map和之前的Collection沒有關係,對元素存取的方式也大不相同,它的方法和前面介紹的界面完全無關。
Map的重要方法如下:
V put(K key, V value)
以key物件為識別,將vlaue新增為本集合物件之元素。
V get(Object key)
取得識別代號為key的元素。
V remove(Object key)
刪除識別代號為key的元素。
void clear()
刪除集合物件中的所有元素。
int size()
取得集合物件的元素個數。
Collection<V> values()  
將集合物件中的所有元素,建構成Cellection型別物件。
 
4-1 HashMap
以預設方式排列key(同HashSet),也就是key的排列方式與新增順序無關。
例一:
import java.util.*;
public class MapTest{
 public static void main(String[] args){
  HashMap map=new HashMap();
  String[] s={"A","B","C"};
  map.put(s[0],new String("Angel"));
  map.put(s[1],new String("Baseball"));
  map.put(s[2],new String("Car"));
  Collection c=map.values();
  for(Object o:c)
   System.out.println(o);
  }
 }
列印結果:Angel Car Baseball
示範主題:1、以key,value的方式新增Map物件的元素。2、將Map物件建構成Collection物件。
 
4-2 LinkedHashMap
以加入的順序排列集合物件中的key。
例二:
import java.util.*;
public class MapTest{
 public static void main(String[] args){
  HashMap map=new HashMap();
  String[] s={"A","B","C"};
  map.put(s[0],new String("Angel"));
  map.put(s[1],new String("Baseball"));
  map.put(s[2],new String("Car"));
  for(String key:s)
   System.out.println(map.get(key));
  }
 }
列印結果:Angel Baseball Car
示範主題:用get(key)取得集合物件中之元素。
 
4-3 TreeMap
本類別集合物件會將key之值自動排序。
例一:
import java.util.*;
public class MapTest{
 public static void main(String[] args){
  TreeMap map=new TreeMap();
  String[] s={"a","B","c"};
  map.put(s[0],new String("Angel"));
  map.put(s[1],new String("Baseball"));
  map.put(s[2],new String("Car"));
  Collection c=map.values();
  for(Object o:c)
   System.out.println(o);
  }
}
列印結果:Baseball Angel Car
示範例主題:集合物件中的元素以key值為自動排序依據。
 
4-4 Hashtable
Hashtable物件中元素的排列方式和HashMap是一樣的。它最大的特色,是和List中的Vector一樣,支援執行緒安全。也就是它的方法全部都有宣告synchronized。
 
5. 物件排序
String物件能不能排序?可以。Integer物件能不能排序?可以。Student物件能不能排序?不能。因為我們並沒有設計Student物件比較大小的準則,自然無法排序。
5-1 Comparable Interface
要設計某一個類別所建構的物件之間的比較準則,就必須在宣告類別時,實作java‧lang‧Comparable這個Interface,並 overriding comparTo()這個方法。要注意此界面和之前介紹過的java‧util‧Comparator界面並不一樣。 Comparator型別物件定義的比較準則,是提供給PriorityQueue集合物件使用。而實作本界面的類別所建構的物件,可以在任何環境中進行 比較。
 
將Student‧java修改如下:
public class Student implements Comparable<Student>
{
//其他方法成員
 public int compareTo(Student s){
  if(number.hashCode()>s.getNumber().hashCode())
   return 1;
  if(number.hashCode()<s.getNumber().hashCode())
   return -1;
  return 0;
 }
}
 
5-2 Collections
java‧util‧Collections這是一個類別,不是之前的Collection界面。這個類別的功能與java‧util‧Arrays相似,提供相當多的類別方法成員,來協助我們運算集合物件。對於這些方法我們有概念即可。
例一:
import java.util.*;
public class CollectionsTest{
 public static void main(String[] args){
  LinkedList list=new LinkedList();
  list.add(new String("java"));
  list.add(new String("Java"));
  list.add(new String("scjp"));
  list.add(new String("Scjp"));
  System.out.print("排序前:");
  for(Object s:list)
   System.out.print(s + "\t");
  Collections.sort(list);
  System.out.print("\n排序後:");
  for(Object s:list)
   System.out.print(s+ "\t");
 }
}
列印結果:
排序前:java Java scjp Scjp
排序後:Java Scjp java scjp
示範主題:1、讓沒有排序功能的List物件,也可以排序。2、 Collections中還有接受排序準則物件(Compartor)為參數的sort()。
 
例二:
import java.util.*;
public class CollectionsTest{
 public static void main(String[] args){
  LinkedList list=new LinkedList();
  list.add(new String("java"));
  list.add(new String("Java"));
  list.add(new String("scjp"));
  list.add(new String("Scjp"));
  System.out.println(Collections.binarySearch(list,new String("scjp")));
  System.out.println(Collections.binarySearch(list,new String("SCJP")));
 }
}
列印結果:2 -3。
示範主題:1、取得標的物件在集合物件中的序號。2、若標的物並不存在於集合物件中時,傳回位置代號。(請參閱第四章第四節 陣列比對及其他運算)
 
6. 集合中使用AutoBoxing
在使用集合物件管理大量資料時,如果資料是擁有AutoBoxing機制的物件,善加利用,可以省略一些繁鎖的小程式。
例一:
import java.util.*;
public class AutoBoxingSet{
 public static void main(String[] args){
  HashSet set=new HashSet();
  set.add(1);
  set.add(5.0);
  set.add("Java");
  System.out.println(set);
 }
}
列印結果:[Java, 1, 5.0]
示範主題:AutoBoxing會把值自動建構成對應型別的物件。
 
7. 泛型(Generics)
在使用集合物件管理元素時,要新增於集合物件中的元素,會自動向上轉型為Object型別後新增。因為Java中的所有物件均擁有Object型別,所以集合物件中的元素可以是任何型別的物件,置入時非常方便。
但相對的,取得集合物件中的元素時,所取得的元素一定是Object型別,運算前要先向下轉型,就不是很方便了。
例一:
import java.util.*;
public class GenericsTest{
 public static void main(String[] args){
  LinkedList list=new LinkedList();
  list.add("Java");
  list.add("Java SCJP");
  list.add("Java SCWCD");
  
  int lengthTotal=0;
  for(int a=0;a<list.size();a++){
   Object o=list.get(a);
   lengthTotal+=o.length();
  }
  System.out.println(lengthTotal);
 }
}
執行結果:編譯錯誤。
示範主題:1、list‧get(a)取得之物件為Object型別,雖然它實際上是String物件,但是目前的型別是Object,所以就不能執行子 類別String中宣告的方法length()。2、若將長度運算敍述修改為「lengthTotal+= ((String)o).length();」,則列印結果為:23。
 
7-1 基本使用
若集合物件之中要管理的元素,確定只有單一型別(例:String),則可以用泛型機制來免除向下轉型之作業。
例一:
import java.util.*;
public class GenericsTest{
 public static void main(String[] args){
  LinkedList<String> list=new LinkedList<String>();
  list.add("Java");
  list.add("Java SCJP");
  list.add("Java SCWCD");
  
  int lengthTotal=0;
  for(int a=0;a<list.size();a++){
   String o=list.get(a);
   lengthTotal+=o.length();
  }
  System.out.println(lengthTotal);
 }
}
列印結果:23。
示範主題:1、在宣告集合物件的參考變數時,於類別名稱後方加上“<型別>”,搭配建構方法的小括號之前加上的“<型別>”,即表示本集合物件只接受指定 型別的物件。2、在建構方法的小括號之前也須加上“<型別>”,若沒有加也可以編譯及執行,但編譯時會產生警告。3、集合物件執行get()所取得的元 素,不必向下轉型即為泛型中宣告之型別。
 
7-2 自訂泛型類別
在說明文件中,我們可以看到很多類別及方法有宣告“<型別>”。以類別而言代表:本類別可以使用泛型機制,來限制集合物件中元素的型別;以方法而言代表:本方法可以搭配類別宣告的泛型型別來執行泛型機制。當然我們自行開發的類別也可以這樣宣告。
例:
public class GenericsTest{
 public static void main(String[] args){
  MyClass<String> mc=new MyClass<String>();
  mc.setX("Java","SCWCD");
  System.out.println(mc.getX());
 }
}
class MyClass<A>{
 private int x;
 public void setX(A o1,A o2 ){
  x=o1.hashCode()+o2.hashCode();
 }
 public int getX(){
  return x;
 }
}
檔案重點:1、類別宣告時的“<A>”表示本類別可以接受泛型機制,‘A’只是一個代號,方便類別中的方法搭配宣告,要叫什麼都可以。2、方法中的代號必須和類別搭配。3、setX()的參數列限定了兩個參數的型別,都必須是建構物件時指定之泛型型別的物件。
列印結果:81035498
示範主題:自訂有泛型功能的類別及方法成員。
 
若方法的參數是集合物件時,可以使用:「1、<?>代表所有型別。2、<? extends E>代表所有E型別的子型別」,來宣告該集合物件參數,可以接受的泛型型別。
例(請參閱JDK文件):
Class LinkedList<E>
本類別接受泛型宣告
add(int index, E element)
新增以類別宣告之泛型型別(E)所建構之物件。
removeAll(Collection<?> c)
刪除任意型別(不限定為E)之Collection物件
addAll(Collection<? extends E> c)
新增以類別宣告之泛型型別(E)及其子類別建構之Collection物件。
最後,泛型中所謂的型別,不包含基本資料型別。
 
7-3 泛型與多型
宣告泛型的類別所建構的物件是多型的。
例一:
List<Object> list=new LinkedList<Object>();
LinkedList<Object> list2=(LinkedList)list;
LinkedList<String> list3=list2;
示範主題:1、new LinkedList<Object>()建構的物件是多型的,可以指派給List<Object>宣告的參考變數。2、可以向下 轉型,指派給LinkedList<Object>宣告的參考變數。3、但是泛型的宣告視為類別宣告的一部份,若泛型宣告的型別不一樣,就不可以指派。
泛型宣告的型別也是適用多型機制的。
 
例二:
LinkedList<Object> list=new LinkedList<Object>();
list.add(new Object());
list.add(new String("Java"));
list.add(new StringBuffer("JAVA"));
list.add(5);
System.out.println(list);
以上程式碼是合法的。泛型型別宣告為Object,則只要是Object型別物件,都是合法的。
 
8. 認證重點整理
8-1 Set Interface
  • 财 從任何型別的集合物件中取出元素時,各元素的型別均為Object。
  • 财 Set這個界面的特色,便是對集合中的物件沒有建立識別系統。
  • 财 Set集合物件中的元素值不能重複。
  • 财 Set沒有辦法取得集合中某一個指定的元素。
  • 财 Set可以新增null,但只能一個,因為值不能重複。
  • 财 HashSet對於集合中的元素是以預設方式排列,也就是不會依照加入的順序排列。
  • 财 LinkedHashSet集合物件中的元素,是以新增的順序排列,也就是先進先出。
  • 财 TreeSet集合物件中的元素會從小到大自動排序。
  • 财 因為TreeSet集合物件有自動排序功能,若集合物件中的元素無法比較大小時,便會產生錯誤訊息。
  • 财 TreeSet集合物件中若新增null為元素,亦會造成執行時期錯誤(因為無法比較大小)。
  • 财 字串排序比對方式:1、以字元碼比對。2、由左向右逐字元比對。
8-2 List Interface
  • 财 List這個界面的特色,便是會對集合物件中的每個元素給予一個序號以資識別,序號從0開始,到元素個數減1。
  • 财 List中是可以置入equals()比對值為true的元素的。
  • 财 LinkedList集合物件中的元素,會以新增的順序或指定的位置排列。
  • 财 指定的序號若超出List物件大小,將會造成執行時期錯誤。
  • 财 Vector支援執行緒同步化,也就是這個類別的所有方法均宣告為synchronized。
8-3 Queue Interface
  • 财 Queue集合物件,最大的特色就是提供了取得元素後順便刪除該元素的方法。
  • 财 LinkedList除了實作List界面之外,也實作了Queue界面。
  • 财 LinkedList類別建構的物件,可以執行List的方法,也可以執行Queue的方法。
  • 财 PriorityQueue提供了,List的所有類別所做不到的功能:自動排序。而且它的排序方式還可以自訂。
  • 财 PriorityQueue集合物件就是用Comparator物件來執行自動排序。Comparator是一個界面,裏面有兩個方法,一個叫 compare,另一個叫equals,自訂的排序準則便寫在compare之中,這個方法的運算結果分為負值、0及正值,分別代表小於、等於及大於的關 係。

8-4 Map Interface
  • 财 Map這個界面的特色,是可以讓我們指定一個物件做為元素的識別代號。
  • 财 做為識別代號的物件我們稱之為key,它必須是唯一的。
  • 财 HashMap以預設方式排列key(同HashSet),也就是key的排列方式與新增順序無關。
  • 财 LinkedHashMap以加入的順序排列集合物件中的key。
  • 财 TreeMap集合物件會將key之值自動排序。
  • 财 Hashtable物件中元素的排列方式和HashMap是一樣的。它最大的特色,是和List中的Vector一樣,支援執行緒安全。
8-5 物件排序
  • 财 要設計某一個類別所建構的物件之間的比較準則,就必須在宣告類別時,實作java‧lang‧Comparable這個Interface,並overriding comparTo()這個方法。
  • 财 java‧util‧Collections這是一個類別,不是之前的Collection界面。這個類別的功能與java‧util‧Arrays相似,提供相當多的類別方法成員,來協助我們運算集合物件。
8-6 集合中使用AutoBoxing
  • 财 使用集合物件管理大量資料時,如果資料是擁有AutoBoxing機制的物件,善加利用,可以省略一些繁鎖的小程式。
8-7 泛型(Generics)
  • 财 若集合物件之中要管理的元素,確定只有單一型別(例:String),則可以用泛型機制來免除向下轉型之作業。
  • 财 在宣告集合物件的參考變數時,於類別名稱後方加上“<型別>”,搭配建構方法的小括號之前加上的“<型別>”,即表示本集合物件只接受指定型別的物件。
  • 财 在集合物件中取得的任意元素,不必向下轉型即為泛型中宣告之型別。
  • 财 類別宣告時的“<A>”表示本類別可以接受泛型機制,‘A’只是一個代號,方便類別中的方法搭配宣告,要叫什麼都可以。
  • 财 方法中的代號必須和類別搭配。
  • 财 若方法的參數是集合物件時,可以使用:「1、<?>代表所有型別。2、<? extends E>代表所有E型別的子型別」,來宣告該集合物件參數,可以接受的泛型型別。
  • 财 宣告泛型的類別所建構的物件是多型的。
  • 财 泛型宣告的型別也是適用多型機制的。

沒有留言:

張貼留言