- 「MoreThanJava」 宣揚的是 「學習,不止 CODE」,本系列 Java 基礎教程是自己在結合各方面的知識之后,對 Java 基礎的一個總回顧,旨在 「幫助新朋友快速高質量的學習」。
- 當然 不論新老朋友 我相信您都可以 從中獲益。如果覺得 「不錯」 的朋友,歡迎 「關注 + 留言 + 分享」,文末有完整的獲取鏈接,您的支持是我前進的最大的動力!
Part 1. 分支結構
迄今為止,我們寫的 Java 代碼都是一條一條語句順序執行的,這種代碼結構通常稱之為 順序結構。
然而僅有順序結構並不能解決所有的問題,比如我們設計一個游戲,游戲第一關的通關條件是獲得 1000
分,如果分數到達則進入下一關,如果未到達則 “Game Over”
:
這里就產生了兩個分支,而且這兩個分支只有一個會被執行。類似的場景還有很多,我們將這種結構稱之為 「分支結構」 或 「選擇結構」。
「是否進入下一關」這樣的決策似乎很小,但是在編程中,復雜的決策是由許多這種小的決策組成的。下面是實現是否進入下一關的程序演示:
import java.util.Scanner;
public class Tester {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String answer;
System.out.print("玩家是否達到 1000 分?(Y or N): ");
answer = scan.nextLine();
if ("Y".equals(answer)) {
System.out.println("進入下一關"); // true branch
} else {
System.out.println("Game Over"); // false branch
}
}
}
程序首先提醒用戶用單一的字符 Y
或 N
來回答:
System.out.print("玩家是否達到 1000 分?(Y or N): ");
然后使用 Scanner
類來獲取用戶的輸入:
answer = scan.nextLine();
然后使用 if
關鍵字來判斷用戶輸入的字符是否等於 Y
:
if ("Y".equals(answer))
如果相等則進入 true branch
,否則進入 false branch
。
縮進:
這里
if
下方的縮進是為了讓用戶更容易看到程序的邏輯,編譯器將忽略掉這些縮進。合理的縮進和程序布局很重要,沒有適當的距離和縮進,看程序的邏輯有時會稍顯困難。您也期望盡可能清晰地表明程序在做什么不是嗎?
if 條件語句
在 Java 中,要構造分支結構可以使用 if
、else
關鍵字。
if
語句的基本語法是:
if (條件) {
// 條件滿足時執行的語句
}
當條件滿足時,則會執行 if
語句中的代碼塊兒,否則執行 if
語句塊后面的代碼。
例如:
public class Tester {
public static void main(String[] args) {
int n = 70;
if (n >= 60) {
System.out.println("及格了");
}
System.out.println("END");
}
}
盡管當 if
語句塊只有一行語句時,可以省略花括號 {}
:
if (n >= 60)
System.out.println("及格了");
當這並不是一個好主意。
假設某個時候,突然想給 if
語句塊增加一條語句時:
public class Tester {
public static void main(String[] args) {
int n = 50;
if (n >= 60)
System.out.println("及格了");
System.out.println("恭喜你"); // 注意這條語句不是if語句塊的一部分
System.out.println("END");
}
}
由於使用縮進格式,很容易把兩行語句都看成 if
語句的執行塊,但實際上只有第一行語句是 if
的執行塊。
在使用 git
這些版本控制系統自動合並時更容易出問題,所以不推薦忽略花括號的寫法。(事實上,你使用 IDEA 的自動排版代碼的功能會幫你自動還原成有花括號的寫法,快捷鍵「ctrl + alt + l」)
else 語句
if
語句還可以編寫一個 else { ... }
,當條件判斷為 false
時,將執行 else
的語句塊:
public class Tester {
public static void main(String[] args) {
int n = 70;
if (n >= 60) {
System.out.println("及格了");
} else {
System.out.println("掛科了");
}
System.out.println("END");
}
}
修改上面代碼的 n
值,觀察 if
條件為 true/ false
時,程序執行的語句塊。
注意,else
不是必須的。
還可以用多個 if ... else if ...
串聯。例如:
public class Tester {
public static void main(String[] args) {
int n = 70;
if (n >= 90) {
System.out.println("優秀");
} else if (n >= 60) {
System.out.println("及格了");
} else {
System.out.println("掛科了");
}
System.out.println("END");
}
}
串聯的效果其實相當於:
if (n >= 90) {
// n >= 90為true:
System.out.println("優秀");
} else {
// n >= 90為false:
if (n >= 60) {
// n >= 60為true:
System.out.println("及格了");
} else {
// n >= 60為false:
System.out.println("掛科了");
}
}
注意順序和臨界條件
在串聯使用多個 if
時,要特別注意判斷順序。觀察下面的代碼:
public class Tester {
public static void main(String[] args) {
int n = 100;
if (n >= 60) {
System.out.println("及格了");
} else if (n >= 90) {
System.out.println("優秀");
} else {
System.out.println("掛科了");
}
}
}
執行發現,n = 100
時,滿足條件 n >= 90
,但輸出的不是 "優秀"
,而是 "及格了"
,原因是 if
語句從上到下執行時,先判斷 n >= 60
成功后,后續 else
不再執行,因此,if (n >= 90)
沒有機會執行了。
正確的方式是按照判斷范圍從大到小依次判斷:
// 從大到小依次判斷:
if (n >= 90) {
// ...
} else if (n >= 60) {
// ...
} else {
// ...
}
或者改寫成從小到大依次判斷:
// 從小到大依次判斷:
if (n < 60) {
// ...
} else if (n < 90) {
// ...
} else {
// ...
}
使用 if
時,還要特別注意邊界條件。例如:
public class Tester {
public static void main(String[] args) {
int n = 90;
if (n > 90) {
System.out.println("優秀");
} else if (n >= 60) {
System.out.println("及格了");
} else {
System.out.println("掛科了");
}
}
}
假設我們期望 90
分或更高為 “優秀”
,上述代碼輸出的卻是 “及格”
,原因是 >
和 >=
效果是不同的。
Part 2. 循環結構
順序結構的程序語句只能被執行一次。如果您想要同樣的操作執行多次,就需要使用循環結構。
Java 中有三種主要的循環結構:
while
循環;do...while
循環;for
循環 (在 Java 5 中還引入了一種主要用於數組的增強型for
循環);
while 循環
while
是最基本的循環,它的結構為:
while ( 布爾表達式 ) {
// 循環內容
}
只要布爾表達式為 true
,循環就會一直執行下去。
實例
public class Test {
public static void main(String args[]) {
int x = 10;
while (x < 20) {
System.out.println("value of x : " + x);
x++;
}
}
}
以上實例編譯運行結果如下:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
do...while 循環
對於 while
語句而言,如果不滿足條件,則不能進入循環。但有時候我們需要即使不滿足條件,也至少執行一次。
do…whil
e 循環和 while
循環相似,不同的是,do…while
循環至少會執行一次。
do {
// 代碼語句
} while (布爾表達式);
注意:布爾表達式在循環體的后面,所以語句塊在檢測布爾表達式之前已經執行了。 如果布爾表達式的值為 true
,則語句塊一直執行,直到布爾表達式的值為 false
。
實例
public class Test {
public static void main(String args[]) {
int x = 10;
do {
System.out.println("value of x : " + x);
x++;
} while (x < 20);
}
}
以上實例編譯運行結果如下:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
for 循環
雖然所有循環結構都可以用 while
或者 do...while
表示,但 Java 提供了另一種語句 —— for
循環,使一些循環結構變得更加簡單。
for
循環執行的次數是在執行前就確定的。語法格式如下:
for(初始化; 布爾表達式; 更新) {
// 代碼語句
}
關於 for
循環有以下幾點說明:
- 最先執行初始化步驟。可以聲明一種類型,但可初始化一個或多個循環控制變量,也可以是空語句。
- 然后,檢測布爾表達式的值。如果為 true,循環體被執行。如果為false,循環終止,開始執行循環體后面的語句。
- 執行一次循環后,更新循環控制變量。
- 再次檢測布爾表達式。循環執行上面的過程。
實例
public class Test {
public static void main(String args[]) {
for (int x = 10; x < 20; x = x + 1) {
System.out.println("value of x : " + x);
}
}
}
以上實例編譯運行結果如下:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
您可以再 IDEA 中快速輸入
fori
關鍵字來快速創建for
循環的基本結構
控制循環
break 關鍵字
break
主要用在循環語句或者 switch
語句中,用來跳出整個語句塊。
break
跳出最里層的循環,並且繼續執行該循環下面的語句。
實例
public class Test {
public static void main(String args[]) {
int[] numbers = {10, 20, 30, 40, 50};
for (int x : numbers) {
// x 等於 30 時跳出循環
if (x == 30) {
break;
}
System.out.print(x);
System.out.print("\n");
}
}
}
以上實例編譯運行結果如下:
10
20
continue 關鍵字
continue
適用於任何循環控制結構中。作用是讓程序立刻跳轉到下一次循環的迭代。
在 for
循環中,continue
語句使程序立即跳轉到更新語句。
在 while
或者 do…while
循環中,程序立即跳轉到布爾表達式的判斷語句。
實例
public class Tester {
public static void main(String args[]) {
int[] numbers = {10, 20, 30, 40, 50};
for (int x : numbers) {
if (x == 30) {
continue;
}
System.out.print(x);
System.out.print("\n");
}
}
}
以上實例編譯運行結果如下:
10
20
40
50
Part 3. 構造程序邏輯
雖然迄今為止我們學習的內容只是 Java 的冰山一角,但是這些內容已經足夠我們來構建程序中的邏輯。
對於編程語言的初學者來說,在學習了 Java 的核心語言元素 (變量、類型、運算符、表達式、分支結構、循環結構等) 之后,必須做的一件事情就是嘗試用所學知識去解決現實中的問題,換句話說就是鍛煉自己把用人類自然語言描述的算法 (解決問題的方法和步驟) 翻譯成 Java 代碼的能力,而這件事情必須通過大量的練習才能達成。
我們在這一 Part 為大家整理了一些經典的案例和習題,希望通過這些例子,一方面幫助大家鞏固之前所學的 Java 知識,另一方面幫助大家了解如何建立程序中的邏輯以及如何運用一些簡單的算法解決現實中的問題。
經典的例子
題目一:尋找水仙花數
說明:水仙花數也被稱為超完全數字不變數、自戀數、自冪數、阿姆斯特朗數,它是一個
3
位數,該數字每個位上數字的立方之和正好等於它本身,例如:13 + 53+ 33=153。
public class Tester {
public static void main(String[] args) {
findAllDaffodilNumberAndPrint();
}
/**
* 查找所有的水仙花數並打印
*/
public static void findAllDaffodilNumberAndPrint() {
for (int num = 100; num < 1000; num++) {
int low = num % 10;
int mid = num / 10 % 10;
int high = num / 100;
// Math.pow(x, 3) 相當於求 x 的 3 次方
if (num == Math.pow(low, 3) + Math.pow(mid, 3) + Math.pow(high, 3)) {
System.out.println(num);
}
}
}
}
題目二:百錢百雞問題
說明:百錢百雞是我國古代數學家張丘建在《算經》一書中提出的數學問題:雞翁一值錢五,雞母一值錢三,雞雛三值錢一。百錢買百雞,問雞翁、雞母、雞雛各幾何?翻譯成現代文是:公雞
5
元一只,母雞3
元一只,小雞1
元三只,用100
塊錢買一百只雞,問公雞、母雞、小雞各有多少只?
public class Tester {
public static void main(String[] args) {
getResultAndPrint();
}
/**
* 獲取百錢百雞的結果並輸出
*/
public static void getResultAndPrint() {
for (int cockNum = 0; cockNum < 20; cockNum++) {
for (int henNum = 0; henNum < 33; henNum++) {
int chickNum = 100 - cockNum - henNum;
if (5 * cockNum + 3 * henNum + chickNum / 3 == 100) {
System.out
.println("公雞:" + cockNum + "只, 母雞:" + henNum + "只, 小雞:" + chickNum + "只");
}
}
}
}
}
上面使用的方法叫做 窮舉法,也稱為 暴力搜索法,這種方法通過一項一項的列舉備選解決方案中所有可能的候選項並檢查每個候選項是否符合問題的描述,最終得到問題的解。
這種方法看起來比較笨拙,但對於運算能力非常強大的計算機來說,通常都是一個可行的甚至是不錯的選擇,而且問題的解如果存在,這種方法一定能夠找到它。
要點回顧
- 分支結構
if
和else
的使用和實例; - 循環結構
while
、do...while
和for
循環的使用和實例; - 控制循環的
break
和continue
實例; - 構建程序邏輯的練習;
練習
練習 1:百分之成績轉換成等級制成績
要求:
- 如果輸入成績在
90
分以上 (含90
分) 輸出A
;80 ~ 90
分 (不含90
) 輸出B
;70 ~ 80
分 (不含80
) 輸出C
;60 ~ 70
分 (不含70
) 輸出D
;60
分以下輸出E
;
參考答案:
import java.util.Scanner;
public class Tester {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int score = scan.nextInt();
if (score >= 90) {
System.out.println("A");
} else if (score >= 80) {
System.out.println("B");
} else if (score >= 70) {
System.out.println("C");
} else if (score >= 60) {
System.out.println("D");
} else {
System.out.println("E");
}
}
}
練習 2:輸入三條邊長,如果能構成三角形就計算周長和面積
參考答案:
import java.util.Scanner;
public class Tester {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
double a = scan.nextDouble();
double b = scan.nextDouble();
double c = scan.nextDouble();
if (a + b > c && a + c > b && b + c > a) {
double perimeter = a + b + c;
System.out.println("三角形周長為:" + perimeter);
double p = (a + b + c) / 2;
double area = Math.sqrt(p * (p - a) * (p - b) * (p - c));
System.out.println("三角形面積為:" + area);
} else {
System.out.println("不能構成三角形!");
}
}
}
練習 3:打印如下所示的三角形圖案
*
**
***
****
*****
*
**
***
****
*****
*
***
*****
*******
*********
參考答案:
import java.util.Scanner;
public class Tester {
public static void main(String[] args) {
System.out.println("請輸入行數:");
Scanner scanner = new Scanner(System.in);
int row = scanner.nextInt();
for (int i = 0; i < row; i++) {
for (int j = row - i - 1; j < row; j++) {
System.out.print("*");
}
// 換行
System.out.println();
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < row; j++) {
if (j < row - i - 1) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
// 換行
System.out.println();
}
for (int i = 0; i < row; i++) {
for (int j = 0; j < row - i - 1; j++) {
System.out.print(" ");
}
for (int j = 0; j < 2 * i + 1; j++) {
System.out.print("*");
}
// 換行
System.out.println();
}
}
}
自取資料
優秀入門資料選取
- Introduction to Computer Science using Java - http://programmedlessons.org/Java9/index.html
- Java零基礎入門教程包含面向對象 - https://study.163.com/course/courseMain.htm?courseId=1003108028
- 網易雲課堂 - 頂尖中文大學計算機專業課程體系 - https://study.163.com/curricula/cs.htm
- TeachYourselfCS-CN (自學計算機科學) - https://github.com/keithnull/TeachYourselfCS-CN
- C語言中文網 Java 入門系列教程 - http://c.biancheng.net/java/10/
- 廖雪峰 Java 教程 - https://www.liaoxuefeng.com/wiki/1252599548343744
- 注重動手能力的 Java 教程 - https://how2j.cn/
推薦書籍
Java 核心技術·卷 I(原書第 11 版)
推薦理由: 這本書在知識體系完整充實的同時,又比《Thinking in Java》暴風式的知識洗禮來得輕松,新人入門書籍強烈推薦!
碼出高效:Java開發手冊
推薦理由: 阿里系出品。從最基礎的計算機基礎入手,到 Java 的方方面面,加上精美的配圖和通俗易懂的解釋,是非常適合新手閱讀的一本兒關於 Java 的技術書籍。
參考資料
- 《Java 核心技術 卷I》(第11版)
- Introduction to Computer Science using Java - http://programmedlessons.org/Java9/index.html#part02
- 菜鳥教程 - https://www.runoob.com/java/
- C語言中文網 Java 入門系列教程 - http://c.biancheng.net/java/10/
- Python 100 天從新手到大師 - https://github.com/jackfrued/Python-100-Days
- 本文已收錄至我的 Github 程序員成長系列 【More Than Java】,學習,不止 Code,歡迎 star:https://github.com/wmyskxz/MoreThanJava
- 個人公眾號 :wmyskxz,個人獨立域名博客:wmyskxz.com,堅持原創輸出,下方掃碼關注,2020,與您共同成長!
非常感謝各位人才能 看到這里,如果覺得本篇文章寫得不錯,覺得 「我沒有三顆心臟」有點東西 的話,求點贊,求關注,求分享,求留言!
創作不易,各位的支持和認可,就是我創作的最大動力,我們下篇文章見!