一、Java程序结构
顺序结构、选择结构、循环结构是结构化程序设计的3种基本结构,是各种复杂程序的基本构造单元:
上图中的三种结构分别是顺序结构、选择结构、循环结构。循环结构是指编写完毕的语句按照编写顺序依次被执行;选择结构是指根据数据和中间结果的不同选择执行的语句,选择结构主要由条件语句(也叫盘算语句或者分支语句)组成;循环结构是指在一定的条件下反复执行某段程序的流程结构,其中反复执行的语句称为循环体,而决定循环是否终止的判断条件称为循环条件。
二、条件语句
条件判断语句会根据不同的判断条件执行不同的代码,在java中,条件判断语句主要包括if条件语句和switch多分支语句。
1、if条件语句
if条件语句主要用于告知程序当某一条件成立时,需执行满足该条件的相关语句。if条件语句分为简单的if条件语句、if…else语句和if…else if多分支语句:
(1)简单if条件语句
if (布尔表达式){
语句;
}
-
布尔表达式:必要参数,最后返回的结果必须是一个布尔值。它可以是一个简单的布尔变量或者常量,也可以是关系表达式。
-
语句:可以是一条或多条语句,当布尔表达式的值为true时执行这些语句。若仅有一条语句,则可以省略条件语句中的"{}"。
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a = 100;
if (a == 100) //没有大括号,直接跟在if语句之后
System.out.println("a的值是100");
}
}
Console:
a的值是100
⚠️注意:
(1) 不要在if语句的布尔表达式中对boolean类型变量做“==”运算;
(2) 不直接使用“=”给布尔变量赋值,导致变量值发生更改,if语句作出了错误判断。
(3) 正确写法,即然是布尔值,直接在if语句中进行判断即可。
实例1:判断手机号是否存在
创建TakePhone类,模拟拨打电话场景,如果输入的电话号码不是指定的号码,就提示拨打的号码不存在。
import java.util.Scanner;
public class TakePhone {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*判断手机号是否存在*/
Scanner inn =new Scanner(System.in);
System.out.println("请输入要拨打的电话号码:");
long phoneNumber = inn.nextLong();
if(phoneNumber != 131716172834L)
System.out.println("对不起,您拨打的电话号码不存在!");
inn.close();
}
}
Console:
请输入要拨打的电话号码:
14253785900
对不起,您拨打的电话号码不存在!
(2)if…else语句
if…else语句是条件语句中最常用的一种形式,他会针对某种条件有选择的作出处理。通常表现为“如果满足某种条件,就进行某种处理,否则进行另一种处理”。
if (表达式1){
语句1;
}
else if (表达式2){
语句2;
}
(3)if…else if多分支语句
if…else if语句用于处理某一事件的多种情况。通常表现为“如果满足一个条件,就采取与该条件对应的方式进行处理;如果满足另一条件,则采用另一个条件对应的方式进行处理”。
if (表达式1){
语句1;
}
else if (表达式2){
语句2;
}
...
else if (表达式n){
语句n;
}
- 表达式1~表达式n:必要参数,可以由多个表达式组成,但是最后返回的结果一定要时boolean值。
- 语句1~语句n:可以是一条或多条语句,当表达式1的值为true时,执行语句1;当表达式2的值为true时,执行语句2,以此类推。
if…else if的执行流程如下:
实例2:饭店座位分配
创建Resturan类,声明变量count表示用餐人数,根据人数安排客人到4人桌、8人桌、12人包厢用餐。
import java.util.Scanner;
public class Resturant {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*饭店作为分配*/
Scanner sc = new Scanner(System.in);
System.out.println("欢迎光临,请问用餐人数几位:");
int count =sc.nextInt();
if (count <= 4) {
System.out.println("请客人到大厅4人桌用餐!");
}else if(count >4 && count <=8) {
System.out.println("请客人到大厅8人桌用餐!");
}else if(count >8 && count <= 12) {
System.out.println("请客人到楼上包厢用餐!");
}else {
System.out.println("我们餐厅无法满足12人以上同一张餐桌用餐,您需要分为多桌进行用餐");
}
sc.close();
}
}
Console1:
欢迎光临,请问用餐人数几位:
6
请客人到大厅8人桌用餐!
Console2:
欢迎光临,请问用餐人数几位:
2
请客人到大厅4人桌用餐!
Console3:
欢迎光临,请问用餐人数几位:
13
我们餐厅无法满足12人以上同一张餐桌用餐,您需要分为多桌进行用餐
2、switch多分支语句
在编程中会遇到一种情况:即检测一个变量是否符合某个条件,如果不符合再用另一个值来检测,以此类推。例如给参加奥运会的国家一个编号,那么就有204个编号,当我们要判断参赛队是不是某一个国家时,就需要反复的判断,这时候还用if条件语句完成显然可以成功,但是程序会非常的笨重:
int country = 001;
if (country == 001){
System.out.println("请001号国家到休息区等候!")
}
if (country == 002){
System.out.println("请002号国家到休息区等候!")
}
if (country == 003){
System.out.println("请003号国家到休息区等候!")
}
if (country == 004){
System.out.println("请004号国家到休息区等候!")
}
if (country == 005){
System.out.println("请005号国家到休息区等候!")
}
...... /*此处省略剩下的119个国家代表队*/
上面这个程序太笨重了,需要测试不同的值来给出输出语句。在Java中,可以使用switch多分支语句将动作组织起来,以简单明了的方式实现“多选一”的功能。
switch(用于判断的参数){
case 常量表达式1:语句1;[break;]
case 常量表达式2:语句2;[break;]
case 常量表达式3:语句3;[break;]
......
case 常量表达式n:语句n;[break;]
default:语句n+1;[break;]
}
- switch多分支语句中参数必须时整型、字符型、枚举类型或者字符串类型,常量值1~n必须是与参数兼容的数据类型。
- switch多分支语句首先计算参数的值,如果参数值和某个常量表达式后的值相同,则执行该case语句后的若干个语句,直到遇到break语句为止。此时,如果该case后没有break语句,将继续执行后面的case中的若干个语句直到遇到break语句为止。若没有任何一个常量表达式与参数常量值相同,则自动进入打default后面的语句。
- break语句的跳出整个switch多分支循环的语句。
- default语句可以不写,如果它不存在,而且switch多分支语句中表达式的值不与汾河case的常量值相同,switch则不进行任何处理。
switch多分支语句的执行流程图如下:
实例3:根据考试成绩判断等级
创建Grade类,使用Scanner类在控制台输入成绩,然后使用switch多分支语句判断输入分数属于哪个等级。9-10代表优,8属于良,6-7属于中,0-5属于差。
import java.util.Scanner;
public class Grade {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
System.out.println("请输入成绩:");
int grade =sc.nextInt();
switch (grade) {
case 10:
case 9:
System.out.println("成绩是优!");
break;
case 8:
System.out.println("成绩是良!");
break;
case 7:
case 6:
System.out.println("成绩是中!");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
System.out.println("成绩是差!");
break;
default:
System.out.println("成绩无效!");
}
sc.close();
}
}
Console1:
请输入成绩:
8
成绩是良!
Console2:
请输入成绩:
4
成绩是差!
Console3:
请输入成绩:
-1
成绩无效!
这个结果发现,当成绩为8时,执行了“case8:”后面的语句,输出了“成绩是良”。当成绩是4时,“case4:”后面时没有任何语句的,这时候switch会自动跳转到下一个case,就是“case4”,还是没有语句,于是继续跳转下一个,直到跳转到“case0:”时,找到了处理代码,于是输出了“成绩为差”的结果,然后执行了break,结束了switch多分支语句。当成绩时-1时,switch直接进入了default,执行完后退出。
三、循环语句
1、while循环语句
while语句的循环方式是通过一个条件来控制是否需要反复执行这个语句。
while(条件表达式){
执行语句
}
当条件表达式的返回值为真时,则执行“{}”中的语句,当执行完“{}”中的语句时后,重新判断条件表达式的返回值,直到条件表达式返回的结果为false时,退出循环。
实例4:对1~10 进行相加
创建 GetSum类,在主方法中通过while循环将证书1~10相加,并输出结果。
public class GetSum {
public static void main(String[] args) {
// TODO Auto-generated method stub
int x = 1;
int sum = 0;
while(x <= 10) {
sum = sum + x;
x++;
}
System.out.println("sum = " + sum);
}
}
Console:
sum = 55
2、do…while循环语句
do…while语句的循环方式与while循环语句相似。他们之间的区别是while循环语句时先判断条件是否成立再执行循环体,而do…while循环语句时先执行一次循环之后,在判断条件是否成立。也就是说do…while循环语句中“{}”中的程序段至少要被执行一次。
do{
执行语句
}
while(条件表达式);
do…while与while循环之间明显的区别是do…while循环语句后面多了一个分号“;”。根据do…while循环语句的语法特点总结出do…while的执行流程。
实例5:用户登陆验证
创建LoginService类,首先提示用户输入6位数密码,使用Scanner扫描器获取用户输入的密码,进入do…while循环进行判断,如果用户输入的妈妈不是执行密码,则让用户反复输入,直到输入的密码是正确的为止。
import java.util.Scanner;
public class LoginService {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in); //创建扫描器,获取控制台输入的值
String password; //创建字符串变量用来保护输入的密码
do {
System.out.println("请输入6位数字密码:");
password = sc.nextLine();
}
while (!"930122".equals(password));
System.out.println("登陆成功");
sc.close();
}
}
Console:
请输入6位数字密码:
873783
请输入6位数字密码:
930122
登陆成功
3、for循环语句
for循环是Java循环语句中最有用的循环语句之一。一个for循环可以用来反复执行某条语句,直到某个条件得到满足。
for (表达式1;表达式2;表达式3){
语句
}
- 表达式1:通常是一个赋值语句,负责设置循环的起始值,也就是给控制层循环的变量赋初始值。
- 表达式2:通常是一个条件表达式,用于控制循环的变量和循环变量允许的范围值进行比较。
- 表达式3:通常是一个赋值表达式,对控制循环的变量进行增大或者减小。
- 语句:语句仍然是复合语句。
for 循环的执行流程如下:
- 第一步:先执行表达式1;
- 第二步:判断表达式2,若为真,执行for循环语句中指定的内嵌语句,然后执行第三步。若表达式2为假,则结束循环,转到第五步;
- 第三步:执行表达式3;
- 第四步:返回第二步继续执行;
- 第五步:循环结束,执行for循环之外的语句。
实例6:1~100的累加计算
创建AdditiveFor类,使用for循环完成1~100的累加。
public class AdditiveFor {
public static void main(String[] args) {
// TODO Auto-generated method stub
int sum = 0;
for (int i =1;i<=100;i++) {
sum += i;
}
System.out.println("sum = "+sum);
}
}
Console:
sum = 5050
4、foreach循环语句
foreach循环语句时for循环语句的特殊简化版本,但是foreach语句并不能完全取代for循环语句,不是任何的foreach语句都可以改写成for循环语句版本的。foreach语句并不是一个关键字,只是习惯上将这种特殊的for语句格式称为foreach循环语句。foreach语句在遍历数组等方面为编程人员提供了很大的便利。
for (循环变量x:遍历对象obj){
引用x的语句
}
- 循环变量x:将obj遍历读取的值赋值给x。
- 遍历对象obj:一次读取obj中的元素值。
- 遍历:在数据结构中是指沿着某条路线,依次对树中的每个节点均做一次且仅做一次访问,也可以简单的理解为“对数组或集合中的所有元素依次访问”。数组,就是相同数据类型的元素按照一定顺序排列的集合。
实例7:遍历整型数组
创建Repetition类,在主方法中定义一维整型数组,并使用foreach语句遍历该数组。
public class Repetition {
public static void main(String[] args) {
// TODO Auto-generated method stub
int arr[] = {7,10,1};
System.out.println("一维数组中的元素分别为:");
/*x是指遍历arr的结果*/
for (int a :arr) {
System.out.println(a);
}
}
}
Console:
一维数组中的元素分别为:
7
10
1
5、循环嵌套语句
循环有for循环、while循环和do…while循环3种方式,这3种循环可以相互嵌套:
-
for 循环中套用for循环的格式:
for(...){ for(...){ ... } }
-
while循环中套用while循环的格式:
while(...){ while(...){ ... } }
-
while循环中套用for循环的格式:
while(...){ for(...){ ... } }
实例8:输出乘法口诀
创建Multiplication类,使用两层for循环实现在控制台输出乘法口诀表。
public class Multiplication {
public static void main(String[] args) {
// TODO Auto-generated method stub
int i,j;
for (i = 1; i < 10; i++) {
for(j = 1; j < i+1; j++) {
System.out.print(j+"*"+i+"="+i*j+"\t"); //打印拼接的字符串
}
System.out.println(); //换行
}
}
}
Console1:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
这个结果可以看出,最外层循环控制的是输出的行数,i从1到9,当i为1时,输出一行然后进入内层循环,这里的j是内层的循环变量,循环的次数与i相同,所以可以使用j< i+1来控制,内层的循环次数决定了输出几列。上述程序是先输出j的值,再输出“*”符号,再输出i的值,最后输出的是j*i的结果。内层循环结束后,输出换行,然后开始下一行的循环。
四、跳转语句
跳转语句包含两个方面内容,一个方面时控制循环变量的变化,也就是让循环判断中的逻辑关系表达式变成false,从未达到终止循环的效果;另一方面是控制循环的跳转,控制循环的跳转需要用到break和continue两个关键字,这两条跳转语句的跳转效果不同,break是终断循环,continue是结束本次循环直接执行下一次循环。
1、break语句
使用break可以跳出switch结构。在循环结构中,同样可以使用break跳出当前循环体,从而终止本次循环。
(1)在各种循环语句中使用break语句
- 在while循环中使用break语句:
while(...){
...
break;
...
}
- 在do…while循环中使用break语句:
do{
...
break;
...
}
while(...){
...
}
- 在for循环中使用break语句:
for(...){
...
break;
...
}
实例9:输出数字中的第一个偶数
创建BreakTest类,循环输出1-19的整数值,在遇到第一个偶数的时候使用break语句结束循环。
public class BreakTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
for(int i = 1; i < 20; i++) {
if(i%2 == 0) {
System.out.println(i);
break;
}
}
System.out.println("---end---");
}
}
Console:
2
---end---
⚠️注意:当遇到循环嵌套时,break只会使程序流程跳出包含最内层的循环结构,即只跳出一层循环。
(2)break标签标记功能:
如果想要用break跳出外层循环,可以使用Java提供的“标签”功能:
标签名:循环体{
break 标签名;
}
- 标签名:任意标识符
- 循环体:任意循环语句
- break 标签名:break跳出指定的循环体,次循环体的标签名必须与break 标签名一致。
实例10:使用break语句跳出指定的循环
创建BreakOutsideNested类,在主方法中编写两层for循环,并给外层循环添加标签,当内层循环4次时,结束所有循环。
public class BreakOutsideNested {
public static void main(String[] args) {
// TODO Auto-generated method stub
Loop: for(int i=0 ;i < 3; i++) { //在for循环前标签标记
for(int j=0; j < 6; j++) { //如果j=4,就结束外层循环
if (j == 4) {
break Loop; //跳出Loop标签标记的循环体
}
System.out.println("i=" + i + "j=" +j); //输出i和j的值
}
}
}
}
Console:
i=0j=0
i=0j=1
i=0j=2
i=0j=3
2、continue语句
continue语句是针对break语句的补充。continue语句不是立即跳出循环体,而是跳出本次循环,进行下一循环。在for循环语句中遇到continue后,首先执行循环的增量部分,然后进行条件测试。在while和do…while中遇到continue语句,则使控制直接回到条件测试部分。
(1)三种循环中使用continue语句
- 在while循环中使用continue
while(...){
...
continue;
...
}
- 在do…while循环中使用continue
do{
...
continue;
...
}
while(...){
};
- 在for循环中使用continue
for(...){
...
continue;
...
}
实例11:输出数字中的所有偶数
创建ContinueTest类,使用一个for循环输出1~19之间所有值,如果输出的值是奇数,则使用continue跳转出本次循环进入下次循环。
public class ContinueTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
for (int i = 1; i < 20; i++)
{
if ( i % 2 != 0) { // 如果i不是偶数
continue; //跳到下一循环(跳出本次循环)
}
System.out.println(i);
}
}
}
Console1:
2
4
6
8
10
12
14
16
18
和break一样,continue也支持标签标记功能:
标签名:循环体{
continue 标签名;
}
- 标签名:任意标识符
- 循环体:任意循环语句
- continue 标签名: continue 跳出指定的循环体,次循环体的标签名必须与 continue 标签名一致。
五、小结
1、条件控制结构的执行体
if、if…else、if…else if条件控制结构中的执行体有两种情况,一种是{}
中的代码块,另一种是以;
结尾的单行语句或者空语句,这两种都被称为条件执行体。
2、switch多分支语句中表达式的数据类型
switch多分支语句后的表达式的数据类型包括:byte、short、char、int这四种整数类型以及String字符串类型和枚举类型。
3、流程控制语句使用技巧
- 通过使用if条件语句和switch多分支语句,可以基于布尔值类型的测试,将一个程序分成不同部分;
- 通过while、do…while、for循环语句,可以让程序的一部分重复执行,直到满足某个终止条件;
- 使用break、continue跳转语句,可以使条件语句和循环语句变得更灵活。