Download presentation
Presentation is loading. Please wait.
Published by浙 管 Modified 7年之前
1
第7單元 7-1 物件(抽象)的資料型態及相關類別 (Abstract Data Types) 7-2 內部類別 (Inner Class)
2
7-1 物件(抽象)的資料型態 Object Data Types/ADT-Abstract Data Type
由於物件的使用者不被允許直接接觸物件內部的資料,物件乃提供了許多函數,讓使用者可以透過函數處理物件內部的資料,以保持物件資料的完整。
3
7-1 物件(抽象)的資料型態 7-1-1 陣列Array物件
陣列是資料結構的一種,它是由固定數目且資料型態相同的數值或物件Object所組成,而以一個共同的名字來存取。 如下列的anArray是個陣列,陣列長度是8,也就是陣列有8個元素elements,索引用來表示元素位置,anArray[0]是陣列中第一個元素,anArray[6]是陣列中第七個元素,最後一個元素是anArray[陣列長度-1]:
4
7-1 物件(抽象)的資料型態 陣列的產生 陣列的宣告 Declaration 宣告一個變數名稱,準備存放陣列的位址
type variable-name[]; 或 type [] variable-name; 如: int month_days[]; 或 int[] month_days;
5
7-1 物件(抽象)的資料型態 陣列位置的產生Allocation 如: int month_days = new int[12];
array-variable = new type[size]; // 中括號內指定所要配置記憶體空間的大小 如: month_days = new int[12]; 以上陣列的宣告與產生可同時進行: type variable= new type[size]; 如: int month_days = new int[12];
6
7-1 物件(抽象)的資料型態 陣列的使用 這種設定初值的方式不能用在宣告後的元素值設定,如 設定陣列元素的值 設定陣列各元素的初值
如設定一月份有31天:month_days[0] = 31; 或取十二月份的天數:int days=month_days[11] ; 設定陣列各元素的初值 在陣列的宣告同時可以設定陣列各元素的初值 type variable[]={data_list}; 如:int month_days []={31,28,31,30,31,30,31,31,30,31,30,31}; 這種設定初值的方式不能用在宣告後的元素值設定,如 int month_days = new int[12]; month_days ={31,28,31,30,31,30,31,31,30,31,30,31}; 則不被許可
7
7-1 物件(抽象)的資料型態 取得陣列的長度 任何時候在存取陣列元素的資料時,其索引值必須在有效的範圍內,否則會發生系統的錯誤。索引值的有效的範圍是大於等於0,小於陣列長度。所以我們在處理陣列元素時有需要知道陣列的長度如何取得: variable-name.length; 如:int month_days = new int[12]; int months=month_days.length; // 其值為12
8
7-1 物件(抽象)的資料型態 字串的陣列Arrays of String Objects
陣列元素的資料型態不限於基本資料型態Primitive data type,也可以是物件Object的資料型態,如String就是最常用的一種。 如:String[] anArray4 = { "January", "February", "March",”April” };
9
7-1 物件(抽象)的資料型態 陣列的複製Copying Arrays
基本型態的資料可以用指定運算元(=號)來複製,但對於參考型態的資料必須使用特定的函數來執行: System.arrayCopy(from, fromStart, to, toStart, count); from: 被複製的陣列 fromStart: 被複製陣列的起始位置 to: 複製的陣列 toStart: 複製陣列的起始位置 count: 複製的元素個數 如:System.arraycopy(copyFrom, 5, copyTo, 0, 8);
10
7-1 物件(抽象)的資料型態 如果參考型態的資料用指定運算元(=號)來複製,複製的是資料的記憶體位址,而不是資料本身。如宣告另一個陣列叫 char[] copy;然後執行 copy=copyFrom; 則copy陣列變數與copyFrom陣列變數指向同一份陣列資料: Arrays類別新增了copyOf()函數,可以直接傳回一個新的陣列物件,語法是: int[] arr2 = Arrays.copyOf(arr1, arr1.length);
11
7-1 物件(抽象)的資料型態 陣列參數的傳遞 參考型資料如陣列、字串或其他的物件,傳遞的是實際數值所在的位址,也就是說函數所”看”到的資料和呼叫者所”看”到的資料是同一份資料,如下圖所示: double[] adata= {1.1, 2.3, 4.2, 5.0, 6.9}; double average_no = average(adata); public static double average(double[] data) {// 被呼叫的函數
12
7-1 物件(抽象)的資料型態 如果不想讓函數更改到”同一份資料”,就要在函數參數的變數前面加個final的保留字
public static double average(final double[] data) {
13
7-1 物件(抽象)的資料型態 函數的陣列回應值 Return Values 函數產生5個小於10的亂數, 5個亂數以陣列方式回應給呼叫程式
public static int[] randomData(int length, int n) { // 被呼叫的函數Random generator = new Random(); int[] data = new int[length]; for (int i=0; i<length; i++) data[i] = generator.nextInt(n); return data; } 函數回應陣列給呼叫者是傳回陣列的位址
14
7-1 物件(抽象)的資料型態 二維陣列 2D Arrays 陣列的宣告
int[][] locker = new int[3][4]; 二維陣列的實際結構先是矩陣變數指向一個一維陣列,這個一維陣列各元素再指向存放實際資料的地方。
15
7-1 物件(抽象)的資料型態 二維陣列的實際結構先是矩陣變數指向一個一維陣列,這個一維陣列各元素再指向存放實際資料的地方。
雖然二維陣列是一維陣列的一種,但為了思考方便,我們將二維陣列視為一個矩陣Matrix,
16
7-1 物件(抽象)的資料型態 二維陣列的初始化 二維陣列元素值的存取
locker[][]={{2,8,3,4},{9,1,2,-6},{-2,-4,5,6}}; 二維陣列元素值的存取 locker[i][j] 指的是第i行第j列的格子,例中的locker有12個格子,各格子名稱表示如下: locker[0][0] locker[0][1] locker[0][2] locker[0][3] locker[1][0] locker[1][1] locker[1][2] locker[1][3] locker[2][0] locker[2][1] locker[2][2] locker[2][3]
17
7-1 物件(抽象)的資料型態 取二維陣列的行數 取二維陣列的列數 int nrows=locker.length; // = 3
int ncols=locker[0].length; // = 4
18
7-1 物件(抽象)的資料型態 陣列類別 Array Class sort() // 對指定的陣列排序
binarySearch() // 對已排序的陣列進行搜尋,傳回該值所在的索引,如果沒找到就傳回負值 int[] arr = {23, 15, 13, 5, 37, 4, 12 , 7, 24, 25}; Arrays.sort(arr); int find = Arrays.binarySearch(arr, 13); 得到的find值為4
19
7-1 物件(抽象)的資料型態 7-1-2 向量Vector 物件
向量物件的使用 使用向量物件必須在程式前面引述 "import java.util.*;" 或"import java.util.Vector;" 指令。
20
7-1 物件(抽象)的資料型態 向量物件的宣告 增加向量物件的元素 改變向量物件的元素 讀取向量物件的元素 移除向量物件的元素
Vector products = new Vector(); 增加向量物件的元素 products.add(element); 改變向量物件的元素 products.set(n, element); // n為元素位置,element為要置換的新元素 讀取向量物件的元素 element =(objectClass)products.get(n); // objectClass為物件的資料類別 或 element =(objectClass)products.elementAt(n); 移除向量物件的元素 products.remove(n); // n為元素位置
21
7-1 物件(抽象)的資料型態 將數字存到向量物件 字串存到向量物件 存入 Double d = new Double(26.89);
data.add(d); 取出 Double d=(Double)data.get(0); double x=d.doubleValue(); 字串存到向量物件 String s = “Danny”; data.add(s); String s=(String)data.get(0);
22
7-1 物件(抽象)的資料型態 取得向量物件的長度 variable-name.size();
如:int no= products.size();
23
7-1 物件(抽象)的資料型態 7-1-3 字串String類別 字串String物件的產生 以字元陣列為參數產生字串物件
char[] helloArray = { ‘H', 'e', 'l', 'l', 'o' }; String Hello = new String(helloArray); 以字串值為參數產生字串物件 String Hello = new String(“Hello World!”;); 直接宣告字串變數 String Hello = “Hello World!”;
24
7-1 物件(抽象)的資料型態 字串的函數 假設String data = “Hello Java! ”; (注意句尾有個空格)
取得字串的長度 int len = data.length(); // 12 取得字串某個位置的字元 char aChar = data.charAt(0); // H 取得字串中某一段字串 String data1 = data.substring(6, 10); //from [6] to [9], not include [10] String data2=data.substring(6); // from [6] to the end 比較兩字串是否相等 boolean equ = data.eauals(“Hello Java!"); 刪除字串頭尾的空白 String data2 = data.trim();
25
7-1 物件(抽象)的資料型態 字串轉為數字型態的函數 Byte.parseByte(字串) 將字串轉為位元
Short.parseShort(字串) 將字串轉為short整數 Integer.parseInt(字串) 將字串轉為integer整數 Long.parseLong(字串) 將字串轉為long整數 Float.parseFloat(字串) 將字串轉為float浮點數 Double.parseDouble(字串) 將字串轉為double浮點數
26
7-1 物件(抽象)的資料型態 與索引相關的函數 char charAt(int index) 傳回指定索引處的字元
int indexOf(char ch) 傳回指定字元第一個找到的索引位置 int indexOf(String str) 傳回指定字串第一個找到的索引位置 int lastIndexOf(int ch) 傳回指定字元最後一個找到的索引位置 String substring(int beginIndex) 取出指定索引處至字串尾端的子字串 String substring(int beginIndex, int endIndex) 取出指定索引範圍子字串 char[] toCharArray() 將字串轉換為字元Array
27
7-1 物件(抽象)的資料型態 7-1-4. 字串的串接Concatenation
字串的串接直接使用 + 運算子,+ 本來是加法運算子,而它被重新定義Override為可以直接用於字串的串接,如: String hot = “Hot”; System.out.println(“Drink “ + hot + “Java!”); 數值變數也可以+號和字串連續起來。如: System.out.println(“The total is ” + total); int a=10, b=20; System.out.print(“a+b=”+a+b); 結果顯示 a+b=1020而不是我們所期望的a+b=30
28
7-1 物件(抽象)的資料型態 7-1-5 StringBuffer類別
String 的值不能更改, StringBuffer的值可以更改。 StringBuffer 物件的產生 StringBuffer buf1 = new StringBuffer("Hello Java!"); StringBuffer buf2 = new StringBuffer( 10 ); StringBuffer buf3 = new StringBuffer(); StringBuffer物件的函數 buf1.setLength(10); // 改變字串長度為10,hello Java buf1.append(“!!”); // buf1內容變為hello Java!! buf1.insert(0, “Hi! “); // buf1內容變為Hi! hello Java!!
29
7-1 物件(抽象)的資料型態 7-1-6 字串的分離Split
使用StringTokenizer類別必須引進java.util 套件 - import java.util.*; StringTokenizer物件的產生 StringTokenizer tokens = new StringTokenizer("I love my country"); StringTokenizer物件的函數 int tokens.countTokens(); // 讀取Token的數目,本例為4 String tokens.nextToken(); // 讀取指標之後的Token資料, //讀完指標移至下一個 boolean tokentokens.hasMoreTokens(); // 判斷指標之後是否還有Token資料
30
7-1 物件(抽象)的資料型態 使用split函數
Tokenizer函數的用法稍閒麻煩,需要用loop指令去分離字串,split是字串物件的函數,直接引用即可,而以參數指定分隔的符號(delimiter)。 stringToSplit= "I love my country"; String[] tokens = stringToSplit.split(" "); split函數執行的結果是以陣列型態回應。
31
7-1 物件(抽象)的資料型態 7-1-7資料格式化 Data Formatting
資料格式化是將資料根據提供的樣版(pattern)加以套版,產生新的顯示樣子,方便不同場合的閱讀。 數字格式化- DecimalFormat double value= ; String pattern="$###,###.### "; // 設定格式化樣版 DecimalFormat myFormatter = new DecimalFormat(pattern); // 以指定的樣版pattern實作格式化物件myFormatter String output = myFormatter.format(value); // 引用格式化物件的format函數 System.out.println(output); // 將格式化後的字串顯示出來
32
7-1 物件(抽象)的資料型態 Date now = new Date(); // 取得當天的日期物件
日期、時間的格式化- DateFormat的使用: Date now = new Date(); // 取得當天的日期物件 System.out.println(now.toString()); 顯示樣式Sun Mar 04 20:14:11 PDT 2007 如果要顯示其他的樣式,要使用DateFormat 物件中的三種函數: DateFormat.getInstance().format(日期物件) // 顯示最簡短的日期時間 DateFormat.getTimeInstance().format(日期物件) // 格式化時間 DateFormat.getDateTimeInstance().format(日期物件) // 格式化日期時間
33
7-1 物件(抽象)的資料型態 文字訊息格式化 - MessageFormat的使用:
文字訊息格式化容許許多日期、時間以及文字片段插入一段文句中間的任何位置。 At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7. 寫法是先將每個變動資料以物件型態置於一個物件陣列中。然後引用MessageFormat類別的format函數MessageFormat.format(String, Object);產生字串結果。 函數的第一個參數是固定文句和插入點的插入索引與樣版(如下面的句子陰影部份),索引是變動資料在物件陣列中的位址。
34
7-1 物件(抽象)的資料型態 At 12:30 PM on Jul 3, 2053, there was a disturbance in the Force on planet 7. Object[] arguments = { new Integer(7), // 索引值為0 new Date(System.currentTimeMillis()), // 索引值為1 "a disturbance in the Force" // 索引值為2 }; String result = MessageFormat.format( "At {1,time} on {1,date}, there was {2} on planet {0,number,integer}.", arguments); System.out.print(result);
35
7-1 物件(抽象)的資料型態 7-1-8 定型表示式 Regular expression
上節說明資料顯示時可以有一定的式樣,反過來輸入的資料也可以規定必須有一定的式樣,如輸入電話號碼必須是 式樣,這種輸入資料式樣的規定就叫定型表示式。 定型表示式可以用下表的定型碼來規定字串字元的式樣,準備好定型表示式後引用Pattern類別的matches()函數來比對所要檢查的字串。 . 該位置可以是任一字元 \\d 或 [0-9] 該位置必須是數字 \\D或 [^0-9] 該位置必須是非數字 \\s或 [ \t\n\x0B\f\r] 該位置必須是空白字元 \\S或 [^ \t\n\x0B\f\r] 該位置必須是非空白字元 \\w或 [a-zA-Z_0-9] 該位置必須是數字或是文字 \\W或 [^a-zA-Z_0-9] 該位置必須是非數字與文字
36
7-1 物件(抽象)的資料型態 如檢查字串首三字必須是非數字,後三字必須是數字:
String REGEXP = “\\D\\D\\D\\d\\d\\d”; // 定義定型表示式 if (INPUT1.matches(REGEXP)) // 比對字串是否符合定型表示式規定 System.out.println(“INPUT1 Match”); 如果同一定型碼出現許多,可以下表所列方式定義定型表示式:(X表示定型碼) X? X出現一次或完全沒有 X* X出現零次或零次以上 X+ X出現一次或一次以上 X{n} X出現n次 X{n,} X出現至少n次 X{n,m} X出現至少n次,但不超過m次
37
7-1 物件(抽象)的資料型態 也可以使用字元類別做一組一組的比對,如:
String REGEXP = “\\D\\D\\D\\d\\d\\d”; 可改寫為 REGEXP = “\\D{3}\\d{3}” 或REGEXP = “[^0-9]{3}[0-9]{3}” 如檢查身分證號碼A 格式是否正確的定型表示式為\\w\\d{9}。 w是第一個字元必須是字母,d{9}表示要有九位數字。 也可以使用字元類別做一組一組的比對,如: [abc] 屬於a、b或c [abc|xyz] 屬於abc或xyz [^abc] 屬於非a、b、c的字元 [a-zA-Z] 屬於a到z或A到Z [a-d&&[pq]] 屬於a到d且有p與q [a-z&&[^pq]] 屬於a到z且沒有p與q [a-z&&[^h-p]] 屬於a到z且沒有h到p
38
7-1 物件(抽象)的資料型態 例如檢查電子郵件格式是否正確? 電子郵件定型表示式為
電子郵件定型表示式為 String REGEXP if(INPUT1.matches(REGEXP)) System.out.println("INPUT1 format correct"); else System.out.println("INPUT1 format error");
39
7-1 物件(抽象)的資料型態 其他的函數: replaceAll()函數 將字串abcdebcaddbc內的bc改為大寫BC
String INPUT = "abcdebcaddbc"; System.out.print(INPUT.replaceAll(REGEXP, "BC")); replaceFirst()函數 將字串abcdebcaddbc內的第一個bc改為大寫BC System.out.print(INPUT.replaceFirst(REGEXP, "BC")); split()函數 將字串the darwinian devonian explodian chicken以ian為分割點加以分段: String REGEXP ="ian"; String INPUT="the darwinian devonian explodian chicken"; Pattern p = Pattern.compile(REGEXP); String[] x = p.split(INPUT);
40
7-1 物件(抽象)的資料型態 7-1-9 數字類別Numbers Classes 數字類別有許多的子類別: 整數的子類別: 建構函數:
Integer intObj=new Integer(100); // 以整數型式宣告整數物件 Integer intObj=new Integer(“100”); // 以字串型式宣告整數物件 Integer intObj = 100;
41
7-1 物件(抽象)的資料型態 成員函數: intObj.intValue(); // 將整數物件轉成整數數值
intObj.doubleValue(); // 將整數物件轉成小數數值 intObj.toString(); // 將整數物件轉成字串 intObj.byteValue(); // 整數物件轉成字元 intObj1.compareTo(intObj2); // 比較兩個整數物件,小於時回-1、等於時回0、大於時回1 intObj1.equals(intObj2); // 比較兩個整數物件是否相等,並回應true 或false的邏輯值 整數與字串的轉換 int i = Integer.parseInt(s.trim()); // 將字串轉成整數 String s = Integer.toString(int i); // 將整數轉成字串
42
7-1 物件(抽象)的資料型態 7-1-10 數學函數 java.lang.Math中常用的數學函數有:
(type of a) Math.abs(a); // 取a的絕對值 (type of a) Math.max(a,b); // 取a, b最大值 (type of a) Math.min(a,b); // 取a, b最小值 double Math.pow(double a, double b); // 取a的b次方值 (即ab) float Math.random(); // 傳回大於等於0.0,小於1.0的隨機亂數 int Math.round(float a); // 取a的整數值 double Math.sqrt(double a); // 取a的平方根值 (a>=0) double Math.sin(double a); // 取a的sin三角函數值 (a以弳度radian為單位)
43
7-1 物件(抽象)的資料型態 7-1-11 亂數類別Random Class 亂數值的產生除了引用數學函數外,還可使用亂數類別:
Random generator = new Random(); nextInt(n); // 傳回大於等於0,小於n的隨機亂數(整數) nextDouble(); // 傳回大於等於0.0,小於1.0的隨機亂數(小數) 如:產生擲骰子1到6的隨機亂數 Dice_no = 1 + generator.nextInt(6); 或 Dice_no = (int)Math.random()*6 + 1; // 使用數學函數
44
7-2 內部類別 Inner Class 7-2-1 何謂內部類別?
類別中還可以再定義類別,稱之為內部類別Inner class或巢狀類別Nested class。 內部類別可以是繼承某個類別或是實作某個介面或是獨立的類別,它可以直接存取外部類別的變數與函數(包括私用private的),而不必透過參數的傳遞。 內部類別可以分為三種: 成員內部類別(Member inner class) 區域內部類別(Local inner class) 匿名內部類別(Anonymous inner class)
45
7-2 內部類別 Inner Class 成員內部類別(Member inner class)
成員內部類別是直接在外部類別內宣告類別為成員,如同宣告成員變數與成員函數一樣。 public class OuterClass { : public void MyMethod() { } private class InnerClass { // 成員內部類別 : } InnerClass inner=new InnerClass(); }
46
7-2 內部類別 Inner Class 區域內部類別(Local inner class)
區域內部類別是定義於外部類別的函數中,類別的物件生成僅止於該函數中有效 。 public class OuterClass { : public void MyMethod() { class InnerClass { // 區域內部類別 : } InnerClass inner=new InnerClass();
47
7-2 內部類別 Inner Class 匿名內部類別(Anonymous inner class)
匿名內部類別是沒有宣告名稱的內部類別,使用時直接以new產生物件。 public class OuterClass extends Applet { : public void MyMethod() { new ActionListener { // 匿名內部類別 : }
Similar presentations