java基礎語法day04(流程控制語句switch、陣列)
今日內容介紹
1. 流程控制語句(switch)
2. 陣列
第1章 流程控制語句
1.1 選擇結構switch
switch 條件語句也是一種很常用的選擇語句,它和if條件語句不同,它只能針對某個表示式的值作出判斷,從而決定程式執行哪一段程式碼。例如,在程式中使用數字1~7來表示星期一到星期天,如果想根據某個輸入的數字來輸出對應中文格式的星期值,可以通過下面的一段虛擬碼來描述:
用於表示星期的數字
如果等於1,則輸出星期一
如果等於2,則輸出星期二
如果等於3,則輸出星期三
如果等於4,則輸出星期四
如果等於5,則輸出星期五
如果等於6,則輸出星期六
如果等於7,則輸出星期天
對於上面一段虛擬碼的描述,大家可能會立刻想到用剛學過得
switch(用於表示星期的數字) { case 1 : 輸出星期一; break; case 2 : 輸出星期二; break; case 3 : 輸出星期三 break; case 4 : 輸出星期四; break; case 5 : 輸出星期五; break; case 6: 輸出星期六; break; case 7: 輸出星期天; break; }
上面改寫後的虛擬碼便描述了switch語句的基本語法格式,具體如下:
switch (表示式){
case 目標值1:
執行語句1
break;
case 目標值2:
執行語句2
break;
......
case 目標值n:
執行語句n
break;
default:
執行語句n+1
break;
}
在上面的格式中,switch語句將表示式的值與每個case中的目標值進行匹配,如果找到了匹配的值,會執行對應case後的語句,如果沒找到任何匹配的值,就會執行default後的語句。switch語句中的break關鍵字將在後面的做具體介紹,此處,我們只需要知道
需要注意的是,在switch語句中的表示式只能是byte、short、char、int型別的值,如果傳入其它型別的值,程式會報錯。但上述說法並不嚴謹,實際上在JDK5.0中引入的新特性enum列舉也可以作為switch語句表示式的值,在JDK7.0中也引入了新特性,switch語句可以接收一個String型別的值。
1.2 選擇結構switch練習
接下來通過一個案例演示根據數字來輸出中文格式的星期,如下所示。
SwitchDemo01.java
public class SwitchDemo01 {
public static void main(String[] args) {
int week = 5;
switch (week) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期天");
break;
default:
System.out.println("輸入的數字不正確...");
break;
}
}
}
執行結果如圖所示。
圖1-1 執行結果
上述程式碼中,由於變數week的值為5,整個switch語句判斷的結果滿足第17行的條件,因此列印“星期五”,例程中的default語句用於處理和前面的case都不匹配的值,將第3行程式碼替換為int week = 8,再次執行程式,輸出結果如下圖所示。
圖1-2 執行結果
在使用switch語句的過程中,如果多個case條件後面的執行語句是一樣的,則該執行語句只需書寫一次即可,這是一種簡寫的方式。例如,要判斷一週中的某一天是否為工作日,同樣使用數字1~7來表示星期一到星期天,當輸入的數字為1、2、3、4、5時就視為工作日,否則就視為休息日。接下來通過一個案例來實現上面描述的情況,如下所示。【case穿透】
SwitchDemo02.java
public class SwitchDemo02 {
public static void main(String[] args) {
int week = 2;
switch (week) {
case 1:
case 2:
case 3:
case 4:
case 5:
// 當 week 滿足值 1、2、3、4、5 中任意一個時,處理方式相同
System.out.println("今天是工作日");
break;
case 6:
case 7:
// 當 week 滿足值 6、7 中任意一個時,處理方式相同
System.out.println("今天是休息日");
break;
}
}
}
執行結果如下圖所示。
圖1-3 執行結果
上述程式碼中,當變數week值為1、2、3、4、5中任意一個值時,處理方式相同,都會列印“今天是工作日”。同理,當變數week值為6、7中任意一個值時,列印“今天是休息日”。
第2章 陣列
在生活中,我們可能會碰到如下的場景。
現在需要統計某公司員工的工資情況,例如計算平均工資、最高工資等。假設該公司有50名員工,用前面所學的知識完成,那麼程式首先需要宣告50個變數來分別記住每位員工的工資,這樣做會顯得很麻煩。
其實在Java中,我們可以使用一個數組來記住這50名員工的工資。陣列是指一組資料的集合,陣列中的每個資料被稱作元素。在陣列中可以存放任意型別的元素,但同一個數組裡存放的元素型別必須一致。
2.1 陣列的定義
在Java中,可以使用以下格式來定義一個數組。如下
資料型別[] 陣列名 = new 資料型別[元素個數或陣列長度];
int[] x = new int[100];
上述語句就相當於在記憶體中定義了100個int型別的變數,第一個變數的名稱為x[0],第二個變數的名稱為x[1],以此類推,第100個變數的名稱為x[99],這些變數的初始值都是0。為了更好地理解陣列的這種定義方式,可以將上面的一句程式碼分成兩句來寫,具體如下:
int[] x; // 宣告一個int[]型別的變數
x = new int[100]; // 建立一個長度為100的陣列
接下來,通過兩張記憶體圖來詳細地說明陣列在建立過程中記憶體的分配情況。
第一行程式碼 int[] x; 聲明瞭一個變數x,該變數的型別為int[],即一個int型別的陣列。變數x會佔用一塊記憶體單元,它沒有被分配初始值。記憶體中的狀態如下圖所示。
圖1-4 記憶體狀態圖
第二行程式碼 x = new int[100]; 建立了一個數組,將陣列的地址賦值給變數x。在程式執行期間可以使用變數x來引用陣列,這時記憶體中的狀態會發生變化,如下圖所示。
圖1-5 記憶體狀態圖
記憶體分析圖:
陣列記憶體分析圖:
在上圖中描述了變數x引用陣列的情況。該陣列中有100個元素,初始值都為0。陣列中的每個元素都有一個索引(也可稱為角標),要想訪問陣列中的元素可以通過“x[0]、x[1]、……、x[98]、x[99]”的形式。需要注意的是,陣列中最小的索引是0,最大的索引是“陣列的長度-1”。在Java中,為了方便我們獲得陣列的長度,提供了一個length屬性,在程式中可以通過“陣列名.length”的方式來獲得陣列的長度,即元素的個數。
接下來,通過一個案例來演示如何定義陣列以及訪問陣列中的元素,如下所示。
ArrayDemo01.java
public class ArrayDemo01 {
public static void main(String[] args) {
int[] arr; // 宣告變數
arr = new int[3]; // 建立陣列物件
System.out.println("arr[0]=" + arr[0]); // 訪問陣列中的第一個元素
System.out.println("arr[1]=" + arr[1]); // 訪問陣列中的第二個元素
System.out.println("arr[2]=" + arr[2]); // 訪問陣列中的第三個元素
System.out.println("陣列的長度是:" + arr.length); // 列印陣列長度
}
}
執行結果如下圖所示。
圖1-6 執行結果
在上述程式碼中聲明瞭一個int[]型別變數arr,並將陣列在記憶體中的地址賦值給它。在5~7行程式碼中通過角標來訪問陣列中的元素,在第8行程式碼中通過length屬性訪問陣列中元素的個數。從列印結果可以看出,陣列中的三個元素初始值都為0,這是因為當陣列被成功建立後,陣列中元素會被自動賦予一個預設值,根據元素型別的不同,預設初始化的值也是不一樣的。具體如下表所示。
表2-1 元素預設值
資料型別 | 預設初始化值 |
byte、short、int、long | 0 |
float、double | 0.0 |
char | 一個空字元(空格),即’\u0000’ |
boolean | false |
引用資料型別 | null,表示變數不引用任何物件 |
如果在使用陣列時,不想使用這些預設初始值,也可以顯式地為這些元素賦值。接下來通過一個程式來學習如何為陣列的元素賦值,如下所示
ArrayDemo02.java
public class ArrayDemo02 {
public static void main(String[] args) {
int[] arr = new int[4]; // 定義可以儲存4個整數的陣列
arr[0] = 1; // 為第1個元素賦值1
arr[1] = 2; // 為第2個元素賦值2
// 下面的程式碼是列印陣列中每個元素的值
System.out.println("arr[0]=" + arr[0]);
System.out.println("arr[1]=" + arr[1]);
System.out.println("arr[2]=" + arr[2]);
System.out.println("arr[3]=" + arr[3]);
}
}
執行結果如下圖所示。
圖1-7 執行結果
在上述程式碼中,第3行程式碼定義了一個數組,此時陣列中每個元素都為預設初始值0。第2、3行程式碼通過賦值語句將陣列中的元素arr[0]和arr[1]分別賦值為1和2,而元素arr[2]和arr[3]沒有賦值,其值仍為0,因此列印結果中四個元素的值依次為1、2、0、0。
在定義陣列時只指定陣列的長度,由系統自動為元素賦初值的方式稱作動態初始化。
在初始化陣列時還有一種方式叫做靜態初始化,就是在定義陣列的同時就為陣列的每個元素賦值。陣列的靜態初始化有兩種方式,具體格式如下:
1、型別[] 陣列名 = new 型別[]{元素,元素,……};
2、型別[] 陣列名 = {元素,元素,元素,……};
上面的兩種方式都可以實現陣列的靜態初始化,但是為了簡便,建議採用第二種方式。接下來通過一段程式碼來演示陣列靜態初始化的效果,如下所示。
ArrayDemo03.java
public class ArrayDemo03 {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4 }; // 靜態初始化
// 下面的程式碼是依次訪問陣列中的元素
System.out.println("arr[0] = " + arr[0]);
System.out.println("arr[1] = " + arr[1]);
System.out.println("arr[2] = " + arr[2]);
System.out.println("arr[3] = " + arr[3]);
}
}
執行結果如下圖所示。
圖1-8 執行結果
上述程式碼中採用靜態初始化的方式為陣列每個元素賦予初值,分別是1、2、3、4。需要注意的是,第3行程式碼千萬不可寫成int[] arr = new int[4]{1,2,3,4};,這樣寫編譯器會報錯。原因在於編譯器會認為陣列限定的元素個數[4]與實際儲存的元素{1,2,3,4}個數有可能不一致,存在一定的安全隱患。
2.2 陣列遍歷
在運算元組時,經常需要依次訪問陣列中的每個元素,這種操作稱作陣列的遍歷。接下來通過一個案例來學習如何使用for迴圈來遍歷陣列,如下所示。
ArrayDemo04.java
public class ArrayDemo04 {
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 }; // 定義陣列
// 使用for迴圈遍歷陣列的元素
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]); // 通過索引訪問元素
}
}
}
執行結果如下圖所示。
圖1-9 執行結果
上述程式碼中,定義一個長度為5的陣列arr,陣列的角標為0~4。由於for迴圈中定義的變數i的值在迴圈過程中為0~4,因此可以作為索引,依次去訪問陣列中的元素,並將元素的值打印出來。
2.3 陣列的常見問題
陣列在編寫程式時應用非常廣泛,靈活地使用陣列對實際開發很重要。接下來,本節將針對陣列的常見操作進行詳細地講解,如陣列的遍歷、最值的獲取、陣列的排序等。
2.3.1 陣列最值
在運算元組時,經常需要獲取陣列中元素的最值。接下來通過一個案例來演示如何獲取陣列中元素的最大值,如下所示。
ArrayDemo05.java
public class ArrayDemo05 {
public static void main(String[] args) {
int[] arr = { 4, 1, 6, 3, 9, 8 }; // 定義一個數組
int max = arr[0]; // 定義變數max用於記住最大數,首先假設第一個元素為最大值
// 下面通過一個for迴圈遍歷陣列中的元素
for (int x = 1; x < arr.length; x++) {
if (arr[x] > max) { // 比較 arr[x]的值是否大於max
max = arr[x]; // 條件成立,將arr[x]的值賦給max
}
}
System.out.println("max=" + max); // 列印最大值
}
}
執行結果如下圖所示。
圖1-10 執行結果
上述程式碼中,定義了一個臨時變數max,用於記住陣列的最大值。通過for 迴圈獲取陣列中的最大值,賦值給max變數。
首先假設陣列中第一個元素arr[0]為最大值,然後使用for迴圈對陣列進行遍歷,在遍歷的過程中只要遇到比max值還大的元素,就將該元素賦值給max。這樣一來,變數max就能夠在迴圈結束時記住陣列中的最大值。需要注意的是,在for迴圈中的變數i是從1開始的,這樣寫的原因是程式已經假設第一個元素為最大值,for迴圈中只需要從第二個元素開始比較,從而提高程式的執行效率。
2.3.2 陣列異常
2.3.2.1 陣列越界異常
每個陣列的索引都有一個範圍,即0~length-1。在訪問陣列的元素時,索引不能超出這個範圍,否則程式會報錯,如下所示。
ArrayDemo06.java
public class ArrayDemo06 {
public static void main(String[] args) {
int[] arr = new int[4]; // 定義一個長度為4的陣列
System.out.println("arr[0]=" + arr[4]); // 通過角標4訪問陣列元素
}
}
執行結果如下圖所示。
上圖執行結果中所提示的錯誤資訊是陣列越界異常ArrayIndexOutOfBoundsException,出現這個異常的原因是陣列的長度為4,其索引範圍為0~3,而上述程式碼中的第4行程式碼使用索引4來訪問元素時超出了陣列的索引範圍。
所謂異常指程式中出現的錯誤,它會報告出錯的異常型別、出錯的行號以及出錯的原因,關於異常在後面的章節會有詳細地講解。
2.3.2.2 空指標異常
在使用變數引用一個數組時,變數必須指向一個有效的陣列物件,如果該變數的值為null,則意味著沒有指向任何陣列,此時通過該變數訪問陣列的元素會出現空指標異常,接下來通過一個案例來演示這種異常,如下所示。
ArrayDemo07.java
public class ArrayDemo07 {
public static void main(String[] args) {
int[] arr = new int[3]; // 定義一個長度為3的陣列
arr[0] = 5; // 為陣列的第一個元素賦值
System.out.println("arr[0]=" + arr[0]); // 訪問陣列的元素
arr = null; // 將變數arr置為null
System.out.println("arr[0]=" + arr[0]); // 訪問陣列的元素
}
}
執行結果如下圖所示。
圖1-11 執行結果
通過上圖所示的執行結果可以看出,上述程式碼中第4、5行程式碼都能通過變數arr正常地運算元組。第6行程式碼將變數置為null,當第7行程式碼再次訪問陣列時就出現了空指標異常NullPointerException。
空指標異常記憶體圖:
2.4 二維陣列
在程式中可以通過一個數組來儲存某個班級學生的考試成績,試想一下,如果要統計一個學校各個班級學生的考試成績,又該如何實現呢?這時就需要用到多維陣列,多維陣列可以簡單地理解為在陣列中巢狀陣列。在程式中比較常見的就是二維陣列,接下來針對二維陣列進行詳細地講解。
2.4.1 二維陣列的定義格式
二維陣列的定義有很多方式,接下來針對幾種常見的方式進行詳細地講解,具體如下:
第一種方式:
int[][] arr = new int[3][4];
上面的程式碼相當於定義了一個3*4的二維陣列,即二維陣列的長度為3,二維陣列中的每個元素又是一個長度為4的陣列,接下來通過一個圖來表示這種情況,如下圖所示。
圖1-12 二維陣列
第二種方式:
int[][] arr = new int[3][];
第二種方式和第一種類似,只是陣列中每個元素的長度不確定,接下來通過一個圖來表示這種情況,如下圖所示。
圖1-13 二維陣列
第三種方式:
int[][] arr = {{1,2},{3,4,5,6},{7,8,9}};
上面的二維陣列中定義了三個元素,這三個元素都是陣列,分別為{1,2}、{3,4,5,6}、{7,8,9},接下來通過一個圖來表示這種情況,如圖2-54所示。
圖1-14 二維陣列
對二維陣列中元素的訪問也是通過角標的方式,如需訪問二維陣列中第一個元素陣列的第二個元素,具體程式碼如下:
arr[0][1];
二維陣列記憶體分析圖:
2.4.2 二維陣列元素的訪問
操作二維陣列時,經常需要獲取陣列中元素的值。接下來通過一個案例來演示如何獲取陣列中元素值,如下所示。ArrayDemo08.java
class ArrayDemo08 {
public static void main(String[] args){
//定義二維陣列的方式
int[][] arr = new int[3][4];
System.out.println( arr );
System.out.println("二維陣列的長度: " + arr.length);
//獲取二維陣列的3個元素
System.out.println( arr[0] );
System.out.println( arr[1] );
System.out.println( arr[2] );
System.out.println("列印第一個一維陣列的元素值");
System.out.println( arr[0][0] );
System.out.println( arr[0][1] );//訪問的為二維陣列中第1個一維陣列的第2個元素
System.out.println( arr[0][2] );
System.out.println( arr[0][3] );
System.out.println("列印第二個一維陣列的元素值");
System.out.println( arr[1][0] );
System.out.println( arr[1][1] );
System.out.println( arr[1][2] );
System.out.println( arr[1][3] );
System.out.println("列印第三個一維陣列的元素值");
System.out.println( arr[2][0] );
System.out.println( arr[2][1] );
System.out.println( arr[2][2] );
System.out.println( arr[2][3] );
}
}
執行結果如下圖所示:
圖1-15 執行結果
2.4.3 二維陣列元素遍歷與陣列元素累加和
學習完了陣列元素的訪問,我們來學習下陣列的遍歷及陣列的元素累加和操作。
class ArrayDemo09 {
public static void main(String[] args){
//一維陣列的求累加和並遍歷
int[] arr = {10,20,30,40,50};
int sum = 0;
for (int i=0; i<arr.length; i++) {
//System.out.println(arr[i]);
sum += arr[i];
}
System.out.println("sum= " + sum);
System.out.println("---------------------");
//二維陣列的求累加和並遍歷
int[][] arr2 = { {1,2},{3,4,5},{6,7,8,9,10} };
int sum2 = 0;
for (int i=0; i<arr2.length; i++) {
for (int j=0; j<arr2[i].length; j++) {
//System.out.println(arr2[i][j])
sum2 += arr2[i][j];
}
}
System.out.println("sum2= "+ sum2);
}
}
執行結果如下圖所示:
圖1-16 執行結果
2.4.4 公司銷售總和練習
接下來通過一個案例來熟悉二維陣列的使用。
例如要統計一個公司三個銷售小組中每個小組的總銷售額以及整個公司的銷售額。如下所示
第一小組銷售額為{11, 12}萬元
第二小組銷售額為{21, 22, 23}萬元
第三小組銷售額為{31, 32, 33, 34}萬元。
ArrayDemo08.java
public class ArrayDemo10 {
public static void main(String[] args) {
int[][] arr = new int[3][]; // 定義一個長度為3的二維陣列
arr[0] = new int[] { 11, 12 }; // 為陣列的元素賦值
arr[1] = new int[] { 21, 22, 23 };
arr[2] = new int[] { 31, 32, 33, 34 };
int sum = 0; // 定義變數記錄總銷售額
for (int i = 0; i < arr.length; i++) { // 遍歷陣列元素
int groupSum = 0; // 定義變數記錄小組銷售總額
for (int j = 0; j < arr[i].length; j++) { // 遍歷小組內每個人的銷售額
groupSum = groupSum + arr[i][j];
}
sum = sum + groupSum; // 累加小組銷售額
System.out.println("第" + (i + 1) + "小組銷售額為:" + groupSum + " 萬元");
}
System.out.println("總銷售額為: " + sum + " 萬元");
}
}
執行結果如下圖所示。
圖1-17 執行結果
在上述程式碼中,第3行程式碼定義了一個長度為3的二維陣列,並在4~6行程式碼中為陣列的每個元素賦值。例程中還定義了兩個變數sum和groupSum,其中sum用來記錄公司的總銷售額,groupSum用來記錄每個銷售小組的銷售額。當通過巢狀for迴圈統計銷售額時,外層迴圈對三個銷售小組進行遍歷,內層迴圈對每個小組員工的銷售額進行遍歷,內層迴圈每迴圈一次就相當於將一個小組員工的銷售總額統計完畢,賦值給groupSum,然後把groupSum的值與sum的值相加賦值給sum。當外層迴圈結束時,三個銷售小組的銷售總額groupSum都累加到sum中,即統計出了整個公司的銷售總額。
第3章 隨機點名器案例
3.1 案例介紹
隨機點名器,即在全班同學中隨機的打印出一名同學名字。
要做的隨機點名器,它具備以下3個內容:
1) 儲存所有同學姓名
2) 總覽全班同學姓名
3) 隨機點名其中一人,列印到控制檯
在編寫案例前,我們先來學習下本案例中所涉及到的知識點:
陣列
3.2 案例需求分析
在全班同學中隨機的打印出一名同學名字。
我們對本案例進行分析,得出如下分析結果:
1.儲存全班同學名字
2.列印全班同學每一個人的名字
3.在班級總人數範圍內,隨機產生一個隨機數,查詢該隨機數所對應的同學名字
在儲存同學姓名時,如果對每一個同學都定義一個變數進行姓名儲存,則會出現過多孤立的變數,很難一次性將全部資料持有。此時,我們可以使用陣列解決多個數據的儲存問題。
3.3 實現程式碼步驟
編寫CallName.java檔案,完成程式的編寫。
main方法中進行步驟1、2、3的程式碼實現
public static void main(String[] args) {
System.out.println("--------隨機點名器--------");
// 建立一個儲存多個同學名字的容器(陣列)
String[] students = new String[3];
//1.儲存全班同學名字
//2.列印全班同學每一個人的名字
//3.獲取隨機點名到的學生姓名,並列印
}
1.儲存所有同學姓名
/**
* 1.儲存全班同學名字
* 建立一個儲存多個同學名字的容器(陣列)
* 鍵盤輸入每個同學的名字,儲存到容器中(陣列)
*/
//鍵盤輸入多個同學名字儲存到容器中
Scanner sc = new Scanner(System.in);
for (int i = 0; i < students.length; i++) {
System.out.println("儲存第"+i+"個名稱:");
students[i] = sc.next();
}
2.列印全班同學每一個人的名字
/**
* 2列印全班同學每一個人的名字
*/
//遍歷陣列,得到每個同學名字
for (int i = 0; i < students.length; i++) {
String name = students[i];
//列印同學名字
System.out.println("第"+i+"個學生名稱:" + name);
}
3.獲取隨機點名到的學生姓名,並列印
/**
* 3.在班級總人數範圍內,隨機產生一個隨機數
*/
//根據陣列長度,獲取隨機索引
int index = new Random().nextInt(students.length);
//通過隨機索引從陣列中獲取名稱
String name = students[index];
//返回隨機點到的名稱
上述程式碼中,通過隨機數類Random產生一個從0到陣列長度的隨機索引。使用該索引獲取students陣列中對應的值,便得到了全班同學的隨機姓名。
第4章 總結
4.1 知識點總結
1. 陣列
1)它是一個用來儲存同一個資料型別多個元素的一個容器(陣列長度是固定的,陣列中儲存的元素的資料型別要求一致)
2)格式:
格式1:
資料型別[] 陣列名 = new 資料型別[陣列長度];
格式2:
資料型別[] 陣列名 = new 資料型別[]{元素值1,元素值2,..};
格式3:
資料型別[] 陣列名 = {元素值1,元素值2,..};
3)陣列操作的常見問題:
NullPointerException: 空指標異常
ArrayIndexOutOfBoundsException: 陣列越界異常
2. 二維陣列:
1)它是一個包含多個一維陣列的陣列
2)特點:二維陣列中的每個元素都是一個一維陣列
3)格式:
格式1:
資料型別[][] 陣列名 = new 資料型別[m][n];
m: 代表二維陣列中一維陣列的個數
n: 代表每個一維陣列中元素的個數
格式2:
資料型別[][] 陣列名 = new 資料型別[m][];
m: 代表二維陣列中一維陣列的個數
每一個一維陣列通過賦值來確定陣列長度
格式3:
資料型別[][] 陣列名 = {{元素值1,元素值2,..},{元素值1,元素值2,..},..};