星期三, 10月 24, 2012

OCPJP Day 11


enum 列舉


*舊式的列舉型態

Notes:
  • Java 列舉的時候常用 static + final
  • 舊式的列舉型態在runtime 時期才能知道輸入的參數不正確, 但是無法在編譯時期就知道參數不正確.

*舊式的列舉型態存在很多問題
  • 列印出來的資料不具意義
  • 無型別的安全性


*新式列舉型態 enum

Notes:
  • enum 的地位等同於 class 或是 interface
  • 列舉的名稱就是輸出的字串

*enum switch 語法

Notes:
  • 有型別的安全性
  • 不需要寫default


ESeasons.java

package mod11;

public enum ESeasons {
//直接列舉,不需要在後面加上 ;
//SPRING,SUMMER,FALL,WINTER
// 下面是簡化的結果, 其實會被寫成public static final ESeasons SPRING = new ESeasons();
SPRING("春天"),
SUMMER("夏天"),
FALL("秋天"),
WINTER("冬天");
//
private final String name;
private ESeasons(String name){
this.name = name;
}
//
public String toString(){
return name;
}
}

TestEseasons.java

package mod11;

public class TestEseasons {
public static void main(String args[]){
System.out.println(ESeasons.SPRING);
}
}


Lab: 使用 setupDJ 進行反組譯

Notes:
  • linux底下我找到 jd-gui 套件來進行反組譯
    • jd-gui 其實要在32bits 環境, 使用64位元環境要安裝相關套件才可以執行
    • 安裝zypper install libgtk-2_0-0-32bit
    • 安裝zypper install libgthread-2_0-0-32bit


先談Chapter 14 Collection

Collection 三大議題
  • 順序
  • 重複
  • 排序


Notes:
  • Collection 與陣列的不同是, 空間不夠的時候會自動長大.(應用於取得資料未知大小的時候, 因為陣列必須先固定大小)

*Collection 的特性
  • Collection就是物件的群組化
  • 只要是物件或是基本型別(via autoboxing)都可以使用add()方法加入Collection物件中
  • 次序性
  • 重複性(透過 hashcode equals 來判斷)
  • 排序性


*Collection 的階層關係

Notes:

Java Collection 分三大體系
  • Set <<interface>> 沒有順序(不記住加進來的順序), 不可重複(重複的資料會自動被剔除掉)
    • HashSet (Non-Thread-safe)
    • LinkedHashSet (順序,不可重複的Set)
    • SortedSet <<interface>>
      • TreeSet (Non-Thread-safe)(會排序的Set)(排序的方式是用第一個字母出現在萬用字元表內的順序)
  • List <<interface>> 有順序, 可重複
    • ArrayList (Non-Thread-safe) (在查詢的效能較好)
    • Vector (Thread-safe)(多執行緒的環境使用)
      • Stack (Thread-safe) (先進後出資料結構)(利用 push pop 操作)
    • LinkedList (Non-Thread-safe) (在資料異動上面會比較好)(double linked 雙向連結)
  • Queue <<interface>> 先進先出的資料結構(First In First Out)
    • Deque <<interface>>
      • LinkedList
    • Abstract Queue
      • PriorityQueue (Non-Thread-safe) (會排序的Queue)

Notes:
  • Collection.Sort 可以幫List 排序
  • Arrays.Sort 可以幫陣列排序




Lab:

ArrayListDemo.java

package mod14;

import java.util.*;

public class ArrayListDemo {

public static void main(String[] args) {
List fruits = new ArrayList();
fruits.add("Lemon");
fruits.add("Watermelon");
fruits.add("Pineapple");
fruits.add("Cherry");
fruits.add("Strawbarry");
fruits.add("Pineapple");
fruits.add("Cherry");
System.out.println(fruits);
System.out.print("----------------------------");
//Traditional Method only for List not work in Set (Because Set doesn't have index)
int size = fruits.size();
for (int i=0; i < size; i++){
String fruit = (String)fruits.get(i);
System.out.println(fruit+", length = "+fruit.length());
System.out.print("----------------------------");
}
}

}





Notes:
  • 陣列利用迴圈來取出陣列中的元素, 但是Collecton Set 是沒有順序, 所以無法使用 for 迴圈來取出元素, 迴圈只能使用於List (有順序, 記住放進來的物件, 有索引值)


*Iterator 介面的繼承架構

  • 目的在抓出集合物件內的所有資料
  • 搭配 while 迴圈
  • 單向拜訪
  • ListIterator
    • 可以雙向拜訪


*Iterator 的特性
  • Iteration 指的是取出Collection內的每個元素之程序
  • Set物件的Iterator是沒有

HashSetDemo.java

package mod14;

import java.util.*;

public class HashSetDemo {

public static void main(String[] args) {
Set fruits = new HashSet();
fruits.add("Lemon");
fruits.add("Watermelon");
fruits.add("Pineapple");
fruits.add("Cherry");
fruits.add("Strawbarry");
fruits.add("Pineapple");
fruits.add("Cherry");
System.out.println(fruits);
//Iterator Method Set這邊也適用
Iterator it = fruits.iterator();
while( it.hasNext() ){
String fruit2 = ( String ) it.next();
System.out.println(fruit2+", length = "+fruit2.length());
}


}

}

ArrayListDemo.java

package mod14;

import java.util.*;

public class ArrayListDemo {

public static void main(String[] args) {
List fruits = new ArrayList();
fruits.add("Lemon");
fruits.add("Watermelon");
fruits.add("Pineapple");
fruits.add("Cherry");
fruits.add("Strawbarry");
fruits.add("Pineapple");
fruits.add("Cherry");
System.out.println(fruits);
System.out.print("----------------------------");
//Traditional Method only for List not work in Set (Because Set doesn't have index)
//傳統的方式只能用於List 但是不能用於Set
int size = fruits.size();
for (int i=0; i < size; i++){
String fruit = (String)fruits.get(i);
System.out.println(fruit+", length = "+fruit.length());
System.out.print("----------------------------");
//Iterator Method 兩個都可以套用 (List Set)
Iterator it = fruits.iterator();
//使用hasNext() 判斷有沒有下一筆
while( it.hasNext() ){
String fruit2 = ( String ) it.next();
System.out.println(fruit2+", length = "+fruit2.length());
}
}
}

}



*泛型 (Generics)
  • 提供編譯時期(compile-time)的型別安全檢查
  • 省去不必要的轉型




陣列:

String[] fruits = new String[5];
fruits[0] = "Lemon";
fruits[1] = "Watermelon";
fruits[2] = new Date(); // 這個是不允許的
fruits[3] = 100; // 這個是不允許的

//取出
String s1 = fruits[0];


Collection:

ArrayList<String> fruits = new ArrayList<String>();

fruits.add("Lemon");
fruits.add("Apple");
fruits.add(new Date()); // 如果上面有使用泛型 <String>, 那這個就不允許
fruits.add(100); // 如果上面有使用泛型 <String>, 那這個就不允許

//取出
String s1 = (String) fruits.get(0); // 如果上面有使用泛型 <String>, 那就不需要轉型 (String)


Notes:
  • 泛型規定只能放那個型別, 來節省轉型的作法
  • 整個Collection體系都支援泛型

*for each 的語法
  • 簡化collection拜訪的程序
  • 程式碼更簡潔更安全
  • 適用於陣列
  • 使用巢狀迴圈時更加簡單更安全
  • 去除Iterator的缺點

Iterator 容易出錯
  • Iterator變數在每個迴圈出現三次, 這增加程式碼出錯的可能性


沒有留言: