一、前言
记录时间 [2024-04-29]
系列文章简摘:
Java 笔记 01:Java 概述,MarkDown 常用语法整理
Java 笔记 02:Java 开发环境的搭建,IDEA / Notepad++ / JDK 安装及环境配置,编写第一个 Java 程序
Java 笔记 03:Java 基础知识,使用 IDEA 创建 Java 项目、设置注释颜色,以及自动生成 JavaDoc
Java 笔记 04:Java 数据类型基础,数据类型转换,及其相关场景拓展
更多 Java 相关文章,请参考上面专栏哦。
本文讲述了 Java 流程控制相关内容,常见的控制结构主要有三种:顺序结构、选择结构和循环结构。结合案例分析,深入了解这几种结构语句。
二、流程控制概述
Java 中的流程控制是指通过各种语句和结构来控制程序执行的流程,这些控制结构提供了编程语言中实现各种复杂逻辑的基础。
在 Java 程序设计中,常见的控制结构主要有三种:顺序结构、选择结构和循环结构。
- 顺序结构:顺序结构是指程序按照代码书写的顺序依次执行,没有分支或循环。每一条语句都按照它们在代码中的顺序执行,直到到达程序的末尾。
- 选择结构:选择结构根据条件的真假选择不同的执行路径。常见的选择结构有
if-else
语句和switch-case
语句。通过这些语句,程序可以根据不同的条件执行不同的代码块,从而实现分支控制。 - 循环结构:循环结构允许程序多次执行同一段代码,直到满足退出循环的条件。常见的循环结构有 for 循环、while 循环和 do-while 循环。这些循环结构允许程序根据条件重复执行某段代码,从而实现循环控制。
除了这三种主要的控制结构外,还有一些特殊的控制语句,如跳转语句(break
、continue
、return
),它们能够在一定条件下改变程序的执行顺序或跳出当前的控制结构。
三、顺序结构
顺序结构是程序中最简单的控制结构之一,它按照代码的书写顺序,从上到下一步一步地执行,没有条件判断或循环。在 Java 中,顺序结构是指按照代码的顺序依次执行语句。
顺序结构是 Java 的基本结构,任何一种算法都离不开它。
例如,下面是一个简单的 Java 程序,展示了顺序结构:
public class Sequential {
public static void main(String[] args) {
// 第一条语句
System.out.println("Hello, ");
// 第二条语句
System.out.println("world!");
// 第三条语句
System.out.println("This is a sequential structure.");
}
}
这个程序会按照顺序依次执行三条语句,输出如下:
Hello,
world!
This is a sequential structure.
在这个例子中,每一条语句都按照它们在代码中的顺序执行,没有任何条件或循环来改变执行顺序。
这就是顺序结构的特点:简单直接,按照代码书写顺序执行。
四、选择结构
选择结构是编程中常见的一种控制结构,它根据条件的真假选择不同的执行路径。在 Java 中,选择结构通常通过 if-else
语句或 switch-case
语句实现。
- if-else 语句:
if-else
语句允许根据条件的真假执行不同的代码块。 - switch-case 语句:
switch-case
语句根据表达式的值选择执行不同的代码块。
1. if-else
if-else
语句允许根据条件的真假执行不同的代码块。
if
语句至多有 1 个 else
语句,else
语句在所有的 else if
语句之后;
else if
语句可以有很多个;
一旦其中一个分支语句检测为 true
,则其他的分支都不会被执行。
单选择结构
单选择结构通常指的是通过 if
语句实现的条件控制,没有 else
部分的情况。
单选择结构的基本作用:根据条件是否成立选择是否执行特定的代码块。
在 Java 中,单选择结构的语法如下:
if (condition) {
// 如果条件为真,执行这里的代码
}
在这个结构中,程序首先检查 condition
是否为真。如果条件为真,就执行 if
语句块中的代码;如果条件为假,则跳过 if
语句块中的代码,继续执行后面的代码。
下面是一个简单的例子,展示了如何使用单选择结构判断一个数是否大于零:
public class IfDemo01 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int number = scanner.nextInt();
if (number > 0) {
System.out.println("The number is positive.");
}
System.out.println("End of program.");
scanner.close();
}
}
在这个例子中,当用户从键盘中输入一个整数后,程序会检查 number
是否大于零:
- 如果
number
的值确实大于零,则会先输出 “The number is positive.” - 否则,会直接输出 “End of program.”
双选择结构
双选择结构是指在一个条件下有两种不同的执行路径。在 Java 中,双选择结构通常使用带有 if
和 else
的语句来实现。
其语法如下:
if (condition) {
// 如果条件为真,执行这里的代码块
} else {
// 如果条件为假,执行这里的代码块
}
在这个结构中,程序首先检查 condition
是否为真。如果条件为真,则执行 if
语句块中的代码;如果条件为假,则执行 else
语句块中的代码。
下面是一个示例,演示了使用双选择结构判断一个数是否为偶数:
public class IfDemo02 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int number = scanner.nextInt();
if (number % 2 == 0) {
System.out.println(number + " is even.");
} else {
System.out.println(number + " is odd.");
}
scanner.close();
}
}
在这个例子中,程序会检查用户输入 number
是否为偶数:
- 如果
number
除以 2 的余数为 0,则执行if
语句块中的代码,输出偶数判断; - 否则执行
else
语句块中的代码,输出奇数判断。
多选择结构
在 Java 中,多选择结构通常使用 if-else if-else
语句来实现,也被称为多分支结构。
多选择结构允许根据多个条件的真假选择不同的执行路径。
其语法如下:
if (condition1) {
// 如果条件1为真,执行这里的代码块
} else if (condition2) {
// 如果条件1为假,但条件2为真,执行这里的代码块
} else if (condition3) {
// 如果条件1和条件2都为假,但条件3为真,执行这里的代码块
} else {
// 如果以上所有条件都为假,执行这里的代码块
}
在这个结构中,程序首先检查 condition1
是否为真。
-
如果条件 1 为真,则执行
if
语句块中的代码。 -
如果条件 1 为假,则检查
condition2
是否为真;- 如果为真则执行
else if
语句块中的代码; - 依此类推,直到找到一个条件为真,执行相应的代码块;
- 如果为真则执行
-
如果所有条件都为假,则执行
else
语句块中的代码。
下面是一个示例,演示了使用多选择结构判断一个学生的考试成绩等级:
public class IfDemo03 {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个整数:");
int score = scanner.nextInt();
if (score > 100 || score<0) {
System.out.println("成绩不合法");
} else 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("F");
}
scanner.close();
}
}
在这个例子中,程序根据学生的分数进行多条件判断,输出相应的等级。
- 如果分数大于 100 或 小于 0,输出成绩不合法;
- 如果分数大于等于 90 分,则输出 “A”;
- 如果分数在 80 到 89 之间,则输出 “B”;
- 依此类推,直到找到符合条件的代码块或者执行默认的代码块。
嵌套结构
嵌套结构是指在一个条件语句块内部再嵌套另一个条件语句块,以实现更复杂的条件逻辑。
在 Java 中,可以通过在一个 if
语句块中嵌套另一个 if
语句块来实现。
其语法如下:
if (condition1) {
// 外部条件为真时执行
if (condition2) {
// 内部条件为真时执行
} else {
// 内部条件为假时执行
}
} else {
// 外部条件为假时执行
}
在这个结构中,首先会检查外部条件 condition1
是否为真。
- 如果外部条件为真,则进入外部
if
语句块中。- 在外部
if
语句块内部,会继续检查内部条件condition2
是否为真; - 如果内部条件为真,则执行内部
if
语句块中的代码; - 否则执行内部
else
语句块中的代码;
- 在外部
- 如果外部条件为假,则直接执行外部
else
语句块中的代码。
2. switch-case
switch 语法
在 Java 中,多选择结构还可以使用 switch-case
语句来实现,它根据表达式的值选择执行不同的代码块。
在 switch
语句中可以有多个 case
分支,每个 case
分支对应一个可能的值,程序会根据表达式的值来匹配相应的 case
分支。
其语法如下:
switch (expression) {
case value1:
// 如果 expression 的值等于 value1,执行这里的代码
break;
case value2:
// 如果 expression 的值等于 value2,执行这里的代码
break;
// 可以有更多的 case 分支
default:
// 如果 expression 的值与所有 case 不匹配,执行这里的代码
break;
}
在这个结构中,首先会得到 expression
的值,然后将其与 case
中的值进行比较。
- 如果找到了匹配的值,则执行相应的
case
语句块中的代码; - 如果找不到匹配的值,则执行
default
语句块中的代码(如果有)。 break
语句用于退出switch
结构,防止执行其他case
或default
语句块。
下面是一个示例,演示了使用 switch
多选择结构判断一个月份的天数:
public class SwitchDemo {
public static void main(String[] args) {
// 创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("请输入月份:");
int month = scanner.nextInt();
int days;
switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
days = 28; // 或者 29,根据是否闰年而定
break;
default:
days = -1; // 无效的月份
break;
}
System.out.println("Number of days in month " + month + ": " + days);
scanner.close();
}
}
在这个例子中,根据输入的月份 month
,程序使用 switch
结构判断该月份的天数,并输出结果。
switch 可用变量类型
在 Java 中,switch
语句中的表达式(即 switch
关键字后面的变量或表达式)可以是以下几种类型:
- 整数类型:
byte
、short
、int
、long
或其对应的包装类Byte
、Short
、Integer
、Long
; - 字符类型:
char
或其对应的包装类Character
; - 枚举类型:可以使用枚举类型作为
switch
语句的表达式; - 字符串类型:从 Java 7 开始,可以使用字符串
String
类型作为switch
语句的表达式; - 同时,
case
标签必须为字符串常量或字面量。
case 穿透现象
在 Java 中,switch
语句中的 case
穿透(fall-through)现象指的是当某个 case
分支被匹配执行后,其后的 case
分支也会被执行,直到遇到 break
语句或者 switch
结束。
这意味着即使后面的 case
分支条件不满足,仍然会执行其对应的代码块。
分析原因:
case
穿透现象通常是因为没有在每个 case
分支中使用 break
语句导致的。
如果在一个 case
分支的代码块末尾没有使用 break
语句,则程序将会继续执行下一个 case
分支的代码块,直到遇到 break
或者 switch
结束。
解决方法:
要避免 case
穿透现象,可以在每个 case
分支的代码块末尾使用 break
语句来退出 switch
结构。
下面是一个示例,演示了 case
穿透现象:
在这个例子中,当 num
的值为 2 时,程序会依次执行 case 2
、case 3
和 default
分支中的代码块,因为在 case 2
中没有使用 break
语句导致了 case
穿透现象。
public class SwitchDemo02 {
public static void main(String[] args) {
int num = 2;
switch (num) {
case 1:
System.out.println("Number is 1");
case 2:
System.out.println("Number is 2");
case 3:
System.out.println("Number is 3");
default:
System.out.println("Default case");
}
}
}
输出结果将会是:
Number is 2
Number is 3
Default case
switch 中字符串编码
在 Java 中,从 Java 7 开始,switch
语句支持使用字符串作为表达式,以便进行字符串的比较。
但是,字符的本质还是数字。
字符串在 switch
中的比较并不是基于字符串的内容,而是基于字符串对象的引用。
在编译时,Java 编译器会使用一个特殊的方法来生成字符串的哈希码(hash code),然后使用哈希码来加速 switch
语句中字符串的比较。这个哈希码是根据字符串的内容生成的,但它不是字符串的 Unicode 编码。
使用字符串作为 switch
语句的表达式的一个例子如下所示:
public class SwitchDemo03 {
public static void main(String[] args) {
String fruit = "apple";
switch (fruit) {
case "apple":
System.out.println("It's an apple.");
break;
case "banana":
System.out.println("It's a banana.");
break;
default:
System.out.println("It's neither an apple nor a banana.");
}
}
}
在这个示例中,switch
语句中的字符串比较会根据字符串的哈希码进行加速,从而实现快速的字符串匹配。这种方式可以提高程序的性能,特别是当需要比较大量的字符串时。
源码:哈希码查看
在 IDEA 中打开 class 文件,可以进行反编译,查看字符串的哈希码。
public static void main(String[] args) {
String fruit = "apple";
byte var3 = -1;
switch(fruit.hashCode()) {
// -1396355227 哈希码
case -1396355227:
if (fruit.equals("banana")) {
var3 = 1;
}
break;
case 93029210:
if (fruit.equals("apple")) {
var3 = 0;
}
}
switch(var3) {
case 0:
System.out.println("It's an apple.");
break;
case 1:
System.out.println("It's a banana.");
break;
default:
System.out.println("It's neither an apple nor a banana.");
}
}
五、循环结构
循环结构是编程中常见的一种控制结构,它允许程序根据条件重复执行某段代码,直到条件不再满足为止。在 Java 中,常见的循环结构有 while
循环、do-while
循环和 for
循环。
- while 循环:
while
循环在每次迭代之前先检查条件,如果条件为真,则执行循环体中的代码,然后重新检查条件。只有在条件为假时,循环才会终止。 - do-while 循环:
do-while
循环与while
循环类似,但它在每次迭代之后检查条件。这意味着无论条件是否为真,循环体至少会执行一次。 - for 循环:
for
循环是一种特殊的循环结构,它允许初始化变量、设置循环条件和更新变量的步骤都在一个地方进行。通常用于循环次数已知的情况。
1. while 循环
while
循环是 Java 中最基本的循环结构之一,它允许根据条件重复执行一段代码块,直到条件不再满足为止。
while
循环在每次迭代之前先检查条件,如果条件为真,则执行循环体中的代码,然后重新检查条件。只有在条件为假时,循环才会终止。
大多数情况下,需要一个让表达式失效的方式来结束循环。
少部分情况需要循环一直执行,比如服务器的请求响应监听等。
在正常业务编程中,应尽量避免死循环,否则会影响程序性能,甚至造成程序卡死奔溃。
while
循环的语法如下:
while (condition) {
// 循环体,满足条件时执行
}
在这个结构中,condition
是一个布尔表达式,表示循环继续执行的条件。
- 只要条件为真,循环体中的代码就会重复执行;
- 一旦条件为假,循环就会终止,程序将继续执行循环后面的代码。
下面是一个简单的示例,演示了如何使用 while
循环计算 1 到 10 的累加和:
public class WhileDemo01 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
while (i <= 10) {
sum += i;
i++;
}
System.out.println("Sum of numbers from 1 to 10: " + sum);
}
}
在这个示例中,循环会从 i
的初始值为 1 开始,重复执行循环体中的代码,每次将 i
的值加到 sum
中,然后递增 i
。
当 i
的值达到 11 时,条件 i <= 10
不再满足,循环终止。最终输出 1 到 10 的累加和。
2. do…while 循环
do...while
循环是 Java 中的一种循环结构,它与 while
循环相似,但在每次迭代之后检查条件。这意味着无论条件是否为真,循环体至少会执行一次。
do...while
循环的语法如下:
do {
// 循环体,至少执行一次
} while (condition);
在这个结构中,先执行 do
后面的循环体中的代码,然后再检查 condition
是否为真。
- 如果条件为真,则继续执行循环体中的代码,然后重新检查条件。
- 只有在条件为假时,循环才会终止。
下面是一个简单的示例,演示了如何使用 do...while
循环计算 1 到 10 的累加和:
public class DoWhileDemo01 {
public static void main(String[] args) {
int sum = 0;
int i = 1;
do {
sum += i;
i++;
} while (i <= 10);
System.out.println("Sum of numbers from 1 to 10: " + sum);
}
}
在这个示例中,循环会从 i
的初始值为 1 开始,重复执行循环体中的代码,每次将 i
的值加到 sum
中,然后递增 i
。
3. while 与 do…while 区别
while
循环和 do...while
循环都是 Java 中用于实现循环的结构,它们的区别在于条件检查的时间点不同:
- while 先判断后执行,dowhile 先执行后判断。
- while 循环:
while
循环在每次迭代之前先检查条件,如果条件为真,则执行循环体中的代码,然后重新检查条件。如果条件为假,循环立即终止,循环体中的代码不会执行。 - do…while 循环:
do...while
循环在每次迭代之后检查条件。这意味着无论条件是否为真,循环体至少会执行一次。在执行完循环体中的代码之后,程序才会检查条件。如果条件为真,则继续执行循环体中的代码,然后重新检查条件。如果条件为假,循环终止。
主要区别在于 while
循环可能会跳过循环体的执行,而 do...while
循环保证循环体至少执行一次。
写一个案例进行 while 与 do…while 区分:
由于 count = 5
,不满足循环的条件,所以两个循环都没有进入,
- 但是 do…while 会至少执行一次,所以会打印出
Count: 5
- while 则没有任何输出
public class WhileDemo02 {
public static void main(String[] args) {
int count = 5;
System.out.println("Using while loop:");
while (count < 5) {
System.out.println("Count: " + count);
count++;
}
count = 5;
System.out.println("Using do...while loop:");
do {
System.out.println("Count: " + count);
count++;
} while (count < 5);
}
}
4. for 循环
for
循环是 Java 中用于实现循环的一种通用结构,它提供了一种简洁的方式来控制循环的次数。
for
循环是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
for
循环通常用于已知循环次数的情况,它由三个部分组成:初始化、条件判断和更新。
在每次迭代中,程序会先执行初始化部分,然后检查条件是否为真,如果条件为真,则执行循环体中的代码,然后执行更新部分。这个过程会一直重复,直到条件不再满足为止。
初始化部分只执行一次。
for
循环的语法如下:
for (initialization; condition; update) {
// 循环体,满足条件时执行
}
// 死循环写法
for (;;){}
在这个结构中:
initialization
用于初始化循环控制变量,通常是一个赋值语句或者声明语句,可以为空;condition
是一个布尔表达式,表示循环继续执行的条件,可以为空;update
用于更新循环控制变量,通常是递增或递减操作,可以为空。
下面是一个简单的示例,演示了如何使用 for
循环计算 1 到 10 的累加和:
public class ForDemo01 {
public static void main(String[] args) {
int sum = 0;
// IDEA 中使用 for 循环的快捷键:number.for
for (int i = 1; i <= 10; i++) {
sum += i;
}
System.out.println("Sum of numbers from 1 to 10: " + sum);
}
}
在这个示例中,循环会从 i
的初始值为 1 开始,重复执行循环体中的代码,每次将 i
的值加到 sum
中,然后递增 i
。
当 i
的值达到 11 时,条件 i <= 10
不再满足,循环终止。最终输出 1 到 10 的累加和。
5. 增强 for 循环
增强 for 循环,也称为 for-each 循环,是 Java 5 中引入的一种简化迭代集合和数组的循环结构。
它提供了一种更简洁、更易读的方式来遍历数组、集合或其他实现了 Iterable 接口的对象。
增强 for 循环的语法如下:
for (type variable : iterable) {
// 循环体,针对每个元素执行
}
在这个结构中:
type
是集合或数组中元素的数据类型;variable
是迭代过程中用于存储每个元素的变量名,作用域限定在循环语句块内;iterable
是一个数组、集合或其他实现了 Iterable 接口的对象。
下面是一个简单的示例,演示了如何使用增强 for 循环遍历数组:
public class UltraForDemo {
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
System.out.println("Using enhanced for loop:");
for (int number : numbers) {
System.out.println(number);
}
// 改写成普通 for
// numbers.length 数组的长度
System.out.println("改写成普通 for");
for (int i=0; i<numbers.length;i++) {
System.out.println(numbers[i]);
}
}
}
在这个示例中,numbers
是一个整数数组,我们使用增强 for 循环遍历数组中的每个元素,并输出其值。
增强 for 循环会自动迭代数组中的每个元素,并将当前元素赋值给 number
变量,然后执行循环体中的代码。
增强 for 循环在编写简单的循环时非常方便,可以减少代码量并提高可读性。
但需要注意的是,增强 for 循环无法访问循环索引,因此在需要索引的情况下,仍然需要使用传统的 for 循环。
六、总结
本文讲述了 Java 流程控制相关内容,常见的控制结构主要有三种:顺序结构、选择结构和循环结构。结合案例分析,深入了解这几种结构语句。
一些参考资料
狂神说 Java 零基础:https://www.bilibili.com/video/BV12J41137hu/
TIOBE 编程语言走势: https://www.tiobe.com/tiobe-index/
Typora 官网:https://www.typoraio.cn/
Oracle 官网:https://www.oracle.com/
Notepad++ 下载地址:https://notepad-plus.en.softonic.com/
IDEA 官网:https://www.jetbrains.com.cn/idea/
Java 开发手册:https://developer.aliyun.com/ebook/394
Java 8 帮助文档:https://docs.oracle.com/javase/8/docs/api/