• 程序执行的几种常见形式
    1. 顺序结构:程序默认执行流程(if, switch)
    2. 分支结构:判断条件来选择某段程序执行(for while, do-while)
    3. 循环结构:重复执行某段程序多次

分支结构

if语句

if第一种格式

1
2
3
if (条件表达式) {
语句体;
}
  • if 语句中,如果大括号控制的只有一行代码,则大括号可以省略不写。

if第二种格式

1
2
3
4
5
if (条件表达式) {
语句体1;
} else {
语句体2;
}

if第三种格式

1
2
3
4
5
6
7
8
9
10
11
if (条件表达式1) {
语句体1;
} else if (条件表达式2) {
语句体2;
} else if (条件表达式3) {
语句体3;
}
……
else {
语句体n+1;
}

案例练习

适合做值的范围匹配

  • if else分支结构,结合键盘录入技术

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    package study;

    import java.util.Scanner;

    /**
    * if else分支结构
    */
    public class Dome1 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入能喝几斤酒:");
    int a = scanner.nextInt();

    if (a >= 2) {
    System.out.println("老丈人:酒量不错啊小伙子!");
    } else {
    System.out.println("老丈人没有理你。");
    }
    }
    }
  • if else if分支机构,结合键盘录入技术

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    package study;

    import java.util.Scanner;

    /**
    * if else if分支结构
    */
    public class Dome2 {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("请输入考试成绩,将为您匹配奖品:");
    int score = scanner.nextInt();

    if (score <= 100 && score >= 95) {
    System.out.println("脚踏车");
    } else if (score <= 94 && score >=90) {
    System.out.println("游乐园门票");
    } else if (score <= 89 && score >= 80) {
    System.out.println("大黄蜂手办");
    } else if (score < 80 && score >= 0){
    System.out.println("您将获得一顿暴打");
    } else {
    System.out.println("你瞅瞅你输入的是正确分数吗,玩捏?");
    }
    }
    }

switch语句

匹配条件去执行分支, 适合做值精确匹配的分支选择,结构清晰,格式良好

1
2
3
4
5
6
7
8
9
10
11
12
13
14
switch(表达式){
case1:
执行代码...;
break;
case2:
执行代码...;
break;

case 值n-1:
执行代码...;
break;
default:
执行代码n;
}

案例练习

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package study;

import java.util.Scanner;

/**
* switch分支结构
*/
public class Dome3 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("今天周几?(请输入数字1~7)");
int week = scanner.nextInt();

switch (week) {
case 1:
System.out.println("埋头苦干,解决bug");
break;
case 2:
System.out.println("请求大牛程序员帮忙");
break;
case 3:
System.out.println("今晚啤酒、龙虾、小烧烤");
break;
case 4:
System.out.println("主动帮助新来的女程序解决bug");
break;
case 5:
System.out.println("今晚吃鸡");
break;
case 6:
System.out.println("与王婆介绍的小芳相亲");
break;
case 7:
System.out.println("郁郁寡欢、准备上班。");
break;
default:
System.out.println("请输入数字0~7");
}
}
}
  • if、switch分支各自适合做什么业务场景?
    1. if其实在功能上远远强大于switch。
    2. if适合做区间匹配。
    3. switch适合做:值匹配的分支选择、代码优雅。

switch的注意事项

  • 表达式类型只能是byteshortintchar,JDK5开始支持枚举,JDK7开始支持String、不支持doublefloatlong
  • case给出的值不允许重复,且只能是字面量,不能是变量。
  • 不要忘记写break,否则会出现穿透现象。

switch的穿透性

  • 如果代码执行到没有写break的case块,执行完后将直接进入下一个case块执行代码(而且不会进行任何匹配),直到遇到break才跳出分支,这就是switch的穿透性。

  • 什么情况下会出现switch穿透现象?
    case中没有写break。

  • switch穿透性能解决什么问题?
    存在多个case分支的功能代码是一样时,可以用穿透性把流程集中到同一处处理,这样可以简化代码。

案例练习

需求:用户输入月份可以展示该月份的天数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
package study;

import java.util.Scanner;

/**
* switch穿透性的利用
*/
public class Dome4 {
public static void main(String[] args) {
Scanner scanner1 = new Scanner(System.in);
System.out.println("请输入年份:");
int year = scanner1.nextInt();

Scanner scanner2 = new Scanner(System.in);
System.out.println("请输入月份(1~12):");
int mouth = scanner2.nextInt();

switch (mouth) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println(year + "年" + mouth + "月有31天");
break;
case 4:
case 6:
case 9:
case 11:
System.out.println(year + "年" + mouth + "月有30天");
break;
case 2:
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
// 能被4整除但不能被100整除的年份为普通闰年
// 能被400整除的为世纪闰年
System.out.println(year + "年" + mouth + "月有29天");
} else {
System.out.println(year + "年" + mouth + "月有28天");
}
break;
default:
System.out.println("请按要求输入数字!");
}
}
}


循环结构

for循环

1
2
3
for (初始化语句; 循环条件; 迭代语句) {
循环体语句(重复执行的代码);
}

示例:

1
2
3
4
// 输出3次HelloWorld
for (int i = 0; i < 3; i++) {
System.out.println("Hello World");
}

案例1:求和

需求:求1-5之间的数据和,并把求和结果在控制台输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package study;

/**
* for循环案例1:求和
*/
public class Dome6 {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 5; i++) {
sum += i;
System.out.println(sum);
}
}
}

案例2:求奇数和

需求:求1-10之间的奇数和,并把求和结果在控制台输出。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package study;

/**
* for循环案例1:求奇数和
*/
public class Dome7 {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 == 1) {
sum += i;
System.out.println("奇数" + i);
}
}
System.out.println(sum);
}
}

另一种思路是直接生成奇数:

1
2
3
4
for (int i = 1; i <= 10; i+=2) {

}

案例3:水仙花数

  • 需求:在控制台输出所有的“水仙花数”,水仙花数必须满足如下2个要求:

    1. 水仙花数是一个三位数
    2. 水仙花数的个位、十位、百位的数字立方和等于原数
  • 分析:

    1. 定义一个for循环从“100一直到999”。
    2. 每次访问到数据后,提取该数据的:个位、十位、百位数字。
    3. 使用if判断:个位、十位、百位的数字立方和是否等于原数,等于则输出该数据。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package study;

/**
* for循环案例3:水仙花数
*/
public class Dome8 {
public static void main(String[] args) {
// 1. 定义一个for循环从“100一直到999”。
for (int i = 100; i <= 999; i++) {

// 2. 每次访问到数据后,提取该数据的:个位、十位、百位数字。
int a = i % 10;
int b = i / 10 % 10;
int c = i / 100 % 10;

// 3. 使用if判断:个位、十位、百位的数字立方和是否等于原数,等于则输出该数据。
if (a * a * a + b * b * b + c * c * c == i) {
System.out.println("恭喜你发现水仙花数" + i);
}
}
}
}

水仙花数:153、370、371、407

  • 如果还要知道水仙花数的个数怎么办?
    1. 在循环外定义一个变量count用于记录水仙花数。
    2. 每输出水仙花数时,让count++。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      package study;

      /**
      * for循环案例3:水仙花数
      */
      public class Dome8 {
      public static void main(String[] args) {
      int count = 0;
      // 1. 定义一个for循环从“100一直到999”。
      for (int i = 100; i <= 999; i++) {

      // 2. 每次访问到数据后,提取该数据的:个位、十位、百位数字。
      int a = i % 10;
      int b = i / 10 % 10;
      int c = i / 100 % 10;

      // 3. 使用if判断:个位、十位、百位的数字立方和是否等于原数,等于则输出该数据。
      if (a * a * a + b * b * b + c * c * c == i) {
      System.out.println("恭喜你发现水仙花数" + i);
      count++;
      }
      }
      System.out.println("共有" + count + "个水仙花数");
      }
      }

while循环

先判断循环条件再执行。

1
2
3
4
5
初始化语句;
while (循环条件) {
循环体语句(被重复执行的代码);
迭代语句;
}

示例:

1
2
3
4
5
int i = 0;
while (i < 3) {
System.out.println("Hello World");
i++;
}
  • 什么时候用for循环,什么时候用while循环?
    1. 功能上是完全一样的,for能解决的while也能解决,反之亦然。
    2. 使用规范是:知道循环几次:使用for;不知道循环几次(无法确定循环条件)建议使用:while。

案例

  • 需求:世界最高山峰是珠穆朗玛峰(8848.86米=8848860毫米),假如我有一张足够大的纸,它的厚度是0.1毫米。请问,折叠多少次,可以折成珠穆朗玛峰的高度。
  • 思路:这种不清楚要循环多少次的情况可以选择用while实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package study;

/**
* while循环
* 需求:世界最高山峰是珠穆朗玛峰(8848.86米=8848860毫米),
* 假如我有一张足够大的纸,它的厚度是0.1毫米。请问,折叠多少次,可以折成珠穆朗玛峰的高度。
*/
public class Dome9 {
public static void main(String[] args) {
double moutionHeight = 8848860;
double height = 0.1;
int count = 0;

while (height <= moutionHeight) {
height *= 2;
count++;
}
System.out.println("需要折叠" + count + "次");
}
}

答案是仅仅需要折叠27次,一张纸就能达到珠穆朗玛峰的高度,不得不感叹指数级增长的速度太惊人了!

do-while循环

  • 先执行再判断循环条件。
  • do-while循环的特点:一定会先执行一次循环体。
1
2
3
4
5
初始化语句;
do {
循环体语句;
迭代语句;
} while (循环条件);

示例:

1
2
3
4
5
int i = 0;
do {
System.out.println("Hello World!");
i++;
} while( i < 3);

三种循环的区别小结

  • for循环 和 while循环(先判断后执行)

  • do…while (第一次先执行后判断)

  • for循环和while循环的执行流程是一模一样的。

  • 如果已知循环次数建议使用for循环,如果不清楚要循环多少次建议使用while循环。

  • for循环中,控制循环的变量只在循环中可以使用。While循环中,控制循环的变量在循环后还可以继续使用

死循环

  • 一直循环的执行下去,如果没有干预不会停止下来。
1
2
3
for(;;) {
System.out.println("Hello World");
}
1
2
3
4
// 经典做法
while(true) {
System.out.println("Hello World");
}
1
2
3
do {
System.out.println("Hello World");
} while (true);

案例:密码验证

  • 需求:系统密码是520,请用户不断的输入密码验证。

    • 验证不对输出:密码错误;
    • 验证成功输出:欢迎进入系统,并停止程序。
  • 分析:

    1. 定义一个整型变量记录正确的密码:520
    2. 使用while死循环,让用户不断输入数据,与正确密码比对:验证不成功输出:密码错误、验证成功输出:欢迎进入系统,并使用break结束当前循环的执行。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package study;

import java.util.Scanner;

/**
* 死循环的案例:密码验证
*/
public class Dome12 {
public static void main(String[] args) {
int pwd = 520;
Scanner scanner = new Scanner(System.in);

while (true) {
System.out.println("请输入密码:");
int num = scanner.nextInt();
if (num == 520) {
System.out.println("密码验证成功!");
break;
} else {
System.out.println("密码错误,请重新输入!");
}
}
}
}

快捷键 Ctrl + Alt + T 可以快速包裹代码行

循环嵌套

  • 循环中又包含循环

    1
    2
    3
    4
    5
    for(int i = 0; i < 3; i++) {
    for(int j = 0; j < 5; j++) {
    System.out.println("我爱你");
    }
    }

    执行次数 3 * 5 = 15

  • 嵌套循环的特点:外部循环每循环一次,内部循环全部执行完一次。

案例:循环嵌套打印矩形

打印四行五列的矩形:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package study;

/**
* 循环嵌套打印矩形
*/
public class Dome14 {
public static void main(String[] args) {
for (int i = 1; i <= 4; i++) {
for (int j = 1; j <= 5; j++) {
// 不换行输出
System.out.print("*");
}
// 换行输出
System.out.println();
}
}
}

跳转关键字

跳转控制语句介绍

  • break: 跳出并结束当前所在循环的执行。
  • continue: 用于跳出当前循环的当次执行,进入下一次循环

break : 只能用于结束所在循环, 或者结束所在switch分支的执行。
continue : 只能在循环中进行使用,作为循环最后一个语句是不必要的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package study;

import java.sql.SQLOutput;

/**
* 跳转关键字break,continue
*/
public class Dome15 {
public static void main(String[] args) {

// break 终止循环
// for (int i = 1; i <= 20; i++) {
// if (i % 5 == 0) {
// // 5,10,15,20
// System.out.println("hello" + i);
// break;
// }
// }

// continue 跳过当次循环
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue;
} else {
System.out.println("hello" + i);
}
}
}
}

案例技术(随机数Random类)

Random的使用

  • Random随机数技术,作用:用于在程序中获取随机数的技术

  • 使用步骤:

    1. 导包:告诉程序去JDK的哪个包中找随机数技术
    2. 写一行代码代表得到随机数对象
    3. 调用随机数的功能获取0-9的随机数
  • 注意,Random生成随机数的特点:

    • nextInt(n) 功能只能生成 【0至n-1】 之间的随机数,不包含n
  • Random生成区间随机数的技巧:减加法

    • 例如:要生成 1 – 10 之间的随机数,程序怎么实现?
    • 1- 10 => -1 => (0-9) + 1
    • 先减一生成0到9之间的随机数,再加一即可成为1到10之间的
  • Random随机数类生成需要几步,具体是什么样的?

    1. 导包:import java.util.Random;
    2. Random r = new Random();
    3. int number = r.nextInt(10);
  • Random随机数如何生成 65 – 91之间的随机数?

    • 先生成0到26之间的随机数,再加26,即成为26到91之间的数
    1. 65 – 91 => (0-26) + 65
    2. int number = r.nextInt(27) + 65;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import java.util.Random;

/**
* 随机数:生成65到91之间的随机数
*/
public class Dome16 {
public static void main(String[] args) {
Random random = new Random();

// 65到91相差26,共有27个可能生成的数字

// 第一步,生成0~26的数(27种可能)
random.nextInt(27);

// 第二步,全加65
int i = random.nextInt(27) + 65;

System.out.println(i);
}
}

猜数字游戏

  • 需求:随机生成一个1-100之间的数据,提示用户猜测,猜大提示过大,猜小提示过小,直到猜中结束游戏

  • 分析:

    1. 随机生成一个1-100之间的数据
    2. 使用死循环让用户不断提示用户猜测,猜大提示过大,猜小提示过小,猜中结束游戏。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package study;

import java.util.Random;
import java.util.Scanner;

/**
* 随机数与死循环相结合的案例:猜数字游戏
*/
public class Demo17 {
public static void main(String[] args) {
// 随机生成一个1-100之间的数据
Random random = new Random();
int res = random.nextInt(99) + 1;

Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("说出你的想法(1~100):");
int num = scanner.nextInt();

if (num > res) {
System.out.println("您猜怎么着,您猜大了!小一点试试");
} else if (num < res) {
System.out.println("您猜怎么着,您猜小了!大一点试试");
} else {
System.out.println("嘿真是地道,您猜对了!");
break;
}
}
}
}