流程控制语句是用于控制程序中各语句执行顺序的语句,可以把语句组合成能完成一定功能的小逻辑模块。
其流程控制方式采用结构化程序设计中规定的三种基本流程结构,即:

  1. 顺序结构;
  2. 分支结构;
  3. 循环结构。

    顺序结构

    程序从上到下逐行地执行,中间没有任何判断和跳转。

02_Java 基本语法(下)_程序流程控制 - 图1

分支结构

分支结构根据条件,选择性地执行某段代码;有if-elseswitch-case两种分支语句。 凡是可以使用switch-case的结构都可以方便地转换成if-else结构,反之不成立。 在使得代码可读性更好、执行效率更高的条件下,优先使用switch-case结构。

if-else

若多个条件表达式间互斥,语句的上下关系不唯一;若多个条件表达式间有交集,与要仔细判断语句的上下关系。

  1. if-else 结构是可以相互嵌套的;
  2. 如果 if-else 结构中的执行语句只有一行,对应的一对大括号可以省略,但不建议。

满足条件则执行

  1. class IfTest{
  2. public static void main(String[] args){
  3. int heartBeats = 105;
  4. if(heartBeats < 60 || heartBeats > 100){
  5. System.out.println("心率不正常,需要做进一步检查。");
  6. }
  7. System.out.println("心率检查报告结束。");
  8. }
  9. }

02_Java 基本语法(下)_程序流程控制 - 图2
运行结果:

  1. 心率不正常,需要做进一步检查。
  2. 心率检查报告结束。

条件二选一

  1. class IfTest{
  2. public static void main(String[] args){
  3. int age = 20;
  4. if(age < 18){
  5. System.out.println("小朋友你好!");
  6. }else{
  7. System.out.println("你不再是小孩子了。");
  8. }
  9. }
  10. }

02_Java 基本语法(下)_程序流程控制 - 图3
运行结果:

  1. 你不再是小孩子了。

条件多选一

  1. class IfTest{
  2. public static void main(String[] args){
  3. int age = 20;
  4. if(age < 0){
  5. System.out.println("非法数据。");
  6. }else if(age < 12){
  7. System.out.println("你好,小朋友!");
  8. }else if(age < 18){
  9. System.out.println("你好,少年!");
  10. }else if(age < 35){
  11. System.out.println("你好,青壮年!");
  12. }else if(age < 60){
  13. System.out.println("你好,中年!");
  14. }else if(age < 120){
  15. System.out.println("你好,爷爷/奶奶!");
  16. }else{
  17. System.out.println("你是要成仙啊~");
  18. }
  19. }
  20. }

02_Java 基本语法(下)_程序流程控制 - 图4
运行结果:

  1. 你好,青壮年!

从控制台获取 3 个整数,并从小到大输出

  1. import java.util.Scanner;
  2. class NumbersComparing {
  3. public static void main(String[] args) {
  4. Scanner scanner = new Scanner(System.in);
  5. System.out.print("请输入第 1 个整数:");
  6. int i = scanner.nextInt();
  7. System.out.print("请输入第 2 个整数:");
  8. int j = scanner.nextInt();
  9. System.out.print("请输入第 3 个整数:");
  10. int k = scanner.nextInt();
  11. int max = (i >= j && i >= k) ? i : (j >= k) ? j : k;
  12. int min = (i <= j && i <= k) ? i : (j <= k) ? j : k;
  13. System.out.println("从小到大排序之后的值为:");
  14. System.out.println("" + min + ", " + (i + j + k - max - min) + ", " + max);
  15. }
  16. }

输入:-9-678
运行结果:

  1. 请输入第 1 个整数:-9
  2. 请输入第 2 个整数:-67
  3. 请输入第 3 个整数:8
  4. 从小到大排序之后的值为:
  5. -67, -9, 8

彩票游戏

开发一个玩彩票的游戏:随机产生一个两位数彩票,提示用户输入一个两位数,然后按照下面的规则判定用户是否能获奖。如果用户输入的数:

  1. 完全匹配,奖金 10,000 美元;
  2. 数字匹配但顺序不一致,奖金 3,000 美元;
  3. 只有一个数字匹配但满足顺序,奖金 1,000 美元;
  4. 只有一个数字匹配但不满足顺序,奖金 500 美元;
  5. 没有匹配任何一个数字,彩票作废。

    提示:使用Math.random()产生 [0,1) 间的随机数。 随机数范围 [a, b]:(int) (Math.random() * (b - a + 1) + a) 原本的范围为 1,(b-a) 确定放大倍数,用乘法扩大范围,+1 弥补左闭右开,+a 移动位置。 如:随机数范围 10~99,则:(int) (Math.random() * 90 + 10)

  1. import java.util.Scanner;
  2. class TestCaiPiao {
  3. public static void main(String[] args) {
  4. //1. 随机产生一个两位数
  5. int randomNum = (int) (Math.random() * 90 + 10);//得到[10,100),取整后为[10,99]
  6. int tenRandom = randomNum / 10;
  7. int singleRandom = randomNum % 10;
  8. System.out.println(randomNum);
  9. //2、用户输入一个两位数
  10. Scanner scan = new Scanner(System.in);
  11. System.out.print("请输入一个两位数:");
  12. int guessNum = scan.nextInt();
  13. int tenGuess = guessNum / 10;
  14. int singleGuess = guessNum % 10;
  15. if (randomNum == guessNum) {
  16. System.out.println("奖金10,000美元");
  17. } else if (tenRandom == singleGuess && singleRandom == tenGuess) {
  18. System.out.println("奖金3,000美元");
  19. } else if (tenRandom == tenGuess || singleRandom == singleGuess) {
  20. System.out.println("奖金1,000美元");
  21. } else if (tenRandom == singleGuess || singleRandom == tenGuess) {
  22. System.out.println("奖金500美元");
  23. } else {
  24. System.out.println("没中奖");
  25. }
  26. System.out.println("中奖号码是:" + randomNum);
  27. }
  28. }

switch-case

02_Java 基本语法(下)_程序流程控制 - 图5

根据switch表达式中的值,依次匹配各个case中的常量。 一旦匹配成功,进入相应的case结构中,执行其中的语句。 break;语句用于跳出switch-case结构,可选。若这个case中没有break;语句,将依次执行其下的case中的语句,而不再判断case的常量。

switch表达式只能是如下的 6 种数据类型:

  1. byte 类型;
  2. short 类型;
  3. char 类型;
  4. int 类型;
  5. 枚举类型(JDK 5.0 后新增);
  6. String 类型(JDK 7.0 后新增)。

case只能用于声明常量,不能用于声明范围。 如果多个 case 内的语句相同,可以直接合并。

  1. class SwitchText {
  2. public static void main(String[] args) {
  3. String season = "summer";
  4. switch (season) {
  5. case "spring":
  6. System.out.println("春暖花开");
  7. break;
  8. case "summer":
  9. System.out.println("夏日炎炎");
  10. break;
  11. case "autumn":
  12. System.out.println("秋高气爽");
  13. break;
  14. case "winter":
  15. System.out.println("冬雪皑皑");
  16. break;
  17. default:
  18. System.out.println("季节输入有误");
  19. break;
  20. }
  21. }
  22. }

运行结果:

  1. 夏日炎炎

输入日子,计算是该年的第几天

  1. import java.util.Scanner;
  2. class DateSerialNumberCalculation {
  3. public static void main(String[] args) {
  4. Scanner scan = new Scanner(System.in);
  5. System.out.print("请输入年份:");
  6. int year = scan.nextInt();
  7. System.out.print("请输入" + year + "年的月份:");
  8. int month = scan.nextInt();
  9. System.out.print("请输入" + year + "年的日期:");
  10. int day = scan.nextInt();
  11. int dateSerialNumber = 0;
  12. int february = 28;
  13. if (year % 4 == 0 & year % 100 != 0 | year % 400 == 0) {
  14. february = 29;
  15. }
  16. switch (month - 1) {
  17. case 12:
  18. dateSerialNumber += 31;
  19. case 11:
  20. dateSerialNumber += 30;
  21. case 10:
  22. dateSerialNumber += 31;
  23. case 9:
  24. dateSerialNumber += 30;
  25. case 8:
  26. dateSerialNumber += 31;
  27. case 7:
  28. dateSerialNumber += 31;
  29. case 6:
  30. dateSerialNumber += 31;
  31. case 5:
  32. dateSerialNumber += 31;
  33. case 4:
  34. dateSerialNumber += 31;
  35. case 3:
  36. dateSerialNumber += 31;
  37. case 2:
  38. boolean isLeapYear = year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
  39. dateSerialNumber += isLeapYear ? 29 : 28;
  40. case 1:
  41. dateSerialNumber += 31;
  42. }
  43. dateSerialNumber += day;
  44. System.out.println(year + "年的" + month + "月" + day + "日是这年的第" + dateSerialNumber + "天。");
  45. }
  46. }

运行结果 1:

  1. 请输入年份:2020
  2. 请输入2020年的月份:3
  3. 请输入2020年的日期:1
  4. 2020年的31日是这年的第61天。

运行结果 2:

  1. 请输入年份:2021
  2. 请输入2021年的月份:3
  3. 请输入2021年的日期:1
  4. 2021年的31日是这年的第60天。

运行结果 3:

  1. 请输入年份:2020
  2. 请输入2020年的月份:12
  3. 请输入2020年的日期:7
  4. 2020年的127日是这年的第344天。

循环结构

循环结构根据循环条件,重复性的执行某段代码;有whiledo-whilefor三种循环语句。

JDK 1.5 提供了foreach循环,方便地遍历集合、数组元素。

循环语句的 4 个组成部分:

  1. 初始化部分 (init_statement);
  2. 循环条件部分 (test_exp);
  3. 循环体部分 (body_statement);
  4. 迭代部分 (alter_statement)。
    • for (; ; )while (true)结构可以不限制循环次数。
  • 跳出循环的方式有:循环条件返回false;在循环体中执行了break;

02_Java 基本语法(下)_程序流程控制 - 图6

for循环

for (①<init_statement>; ②<test_exp>; ④<alter_statement>) {
③<body_statement>;
} ①-→②-→③-→④-→②-→③-→④-→②-→③-→④-→……-→②

  1. 循环条件部分(test_exp)是boolean类型表达式。当值为true时,执行循环体部分(body_statement);为false时,跳出循环;
  2. 初始化部分(init_statement)可以用逗号分隔以声明多个同一类型的变量;
  3. 迭代部分(alter_statement)可以有多个用逗号分隔的变量更新。

02_Java 基本语法(下)_程序流程控制 - 图7

用 for 循环在控制台打印输出 5 次“Hello World!”

  1. class LoopStructureFor {
  2. public static void main(String[] args) {
  3. for (int n = 1; n <= 5; n++) {
  4. System.out.print("n = " + n);
  5. System.out.println("\tHello World!");
  6. }
  7. }
  8. }

运行结果:

  1. n = 1 Hello World!
  2. n = 2 Hello World!
  3. n = 3 Hello World!
  4. n = 4 Hello World!
  5. n = 5 Hello World!

思考以下代码的运行结果:

  1. class LoopStructureFor {
  2. public static void main(String[] args) {
  3. int num = 1;
  4. for (System.out.print('a'); num <= 3; System.out.print('b'), num++){
  5. System.out.print('c');
  6. }
  7. }
  8. }

运行结果:

  1. acbcbcb

遍历 0~100 以内的偶数,计数并求和

  1. class LoopEvenNum {
  2. public static void main(String[] args) {
  3. int sumEvenNum = 0, countEvenNum = 0;
  4. for (int i = 0; i <= 100; i++) {
  5. if (i % 2 == 0) {
  6. countEvenNum++;
  7. System.out.printf("%d ", i);
  8. sumEvenNum += i;
  9. }
  10. }
  11. System.out.println("\nsumEvenNum = " + sumEvenNum);
  12. System.out.println("countEvenNum = " + countEvenNum);
  13. }
  14. }

运行结果:

  1. 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 76 78 80 82 84 86 88 90 92 94 96 98 100
  2. sumEvenNum = 2550
  3. countEvenNum = 51

倍数判断

从 1 循环到 150,并在每行打印一个值。在每个 3、5、7 的倍数行上分别打印标记。

  1. class MultipleJudgement {
  2. public static void main(String[] args) {
  3. int i;
  4. for (i = 1; i <= 150; i++) {
  5. String add3, add5, add7;
  6. add3 = (i % 3 == 0) ? "[3]" : "";
  7. add5 = (i % 5 == 0) ? "[5]" : "";
  8. add7 = (i % 7 == 0) ? "[7]" : "";
  9. System.out.println(i + " - " + add3 + add5 + add7);
  10. }
  11. }
  12. }

运行结果:

  1. 1 -
  2. 2 -
  3. 3 - [3]
  4. 4 -
  5. 5 - [5]
  6. 6 - [3]
  7. 7 - [7]
  8. 8 -
  9. 9 - [3]
  10. 10 - [5]
  11. 11 -
  12. 12 - [3]
  13. 13 -
  14. 14 - [7]
  15. 15 - [3][5]
  16. 16 -
  17. 17 -
  18. 18 - [3]
  19. 19 -
  20. 20 - [5]
  21. 21 - [3][7]
  22. 22 -
  23. 23 -
  24. 24 - [3]
  25. 25 - [5]
  26. 26 -
  27. 27 - [3]
  28. 28 - [7]
  29. 29 -
  30. 30 - [3][5]
  31. 31 -
  32. 32 -
  33. 33 - [3]
  34. 34 -
  35. 35 - [5][7]
  36. 36 - [3]
  37. 37 -
  38. 38 -
  39. 39 - [3]
  40. 40 - [5]
  41. 41 -
  42. 42 - [3][7]
  43. 43 -
  44. 44 -
  45. 45 - [3][5]
  46. 46 -
  47. 47 -
  48. 48 - [3]
  49. 49 - [7]
  50. 50 - [5]
  51. 51 - [3]
  52. 52 -
  53. 53 -
  54. 54 - [3]
  55. 55 - [5]
  56. 56 - [7]
  57. 57 - [3]
  58. 58 -
  59. 59 -
  60. 60 - [3][5]
  61. 61 -
  62. 62 -
  63. 63 - [3][7]
  64. 64 -
  65. 65 - [5]
  66. 66 - [3]
  67. 67 -
  68. 68 -
  69. 69 - [3]
  70. 70 - [5][7]
  71. 71 -
  72. 72 - [3]
  73. 73 -
  74. 74 -
  75. 75 - [3][5]
  76. 76 -
  77. 77 - [7]
  78. 78 - [3]
  79. 79 -
  80. 80 - [5]
  81. 81 - [3]
  82. 82 -
  83. 83 -
  84. 84 - [3][7]
  85. 85 - [5]
  86. 86 -
  87. 87 - [3]
  88. 88 -
  89. 89 -
  90. 90 - [3][5]
  91. 91 - [7]
  92. 92 -
  93. 93 - [3]
  94. 94 -
  95. 95 - [5]
  96. 96 - [3]
  97. 97 -
  98. 98 - [7]
  99. 99 - [3]
  100. 100 - [5]
  101. 101 -
  102. 102 - [3]
  103. 103 -
  104. 104 -
  105. 105 - [3][5][7]
  106. 106 -
  107. 107 -
  108. 108 - [3]
  109. 109 -
  110. 110 - [5]
  111. 111 - [3]
  112. 112 - [7]
  113. 113 -
  114. 114 - [3]
  115. 115 - [5]
  116. 116 -
  117. 117 - [3]
  118. 118 -
  119. 119 - [7]
  120. 120 - [3][5]
  121. 121 -
  122. 122 -
  123. 123 - [3]
  124. 124 -
  125. 125 - [5]
  126. 126 - [3][7]
  127. 127 -
  128. 128 -
  129. 129 - [3]
  130. 130 - [5]
  131. 131 -
  132. 132 - [3]
  133. 133 - [7]
  134. 134 -
  135. 135 - [3][5]
  136. 136 -
  137. 137 -
  138. 138 - [3]
  139. 139 -
  140. 140 - [5][7]
  141. 141 - [3]
  142. 142 -
  143. 143 -
  144. 144 - [3]
  145. 145 - [5]
  146. 146 -
  147. 147 - [3][7]
  148. 148 -
  149. 149 -
  150. 150 - [3][5]

break关键字的使用

输入两个正整数 m 和 n,求其最大公约数和最小公倍数。

  1. class BreakTestInForLoop {
  2. public static void main(String[] args) {
  3. Scanner scan = new Scanner(System.in);
  4. System.out.print("请输入第 1 个正整数:");
  5. int m = scan.nextInt();
  6. System.out.print("请输入第 2 个正整数:");
  7. int n = scan.nextInt();
  8. int greatestCommonDivisor = 0;
  9. int leastCommonMultiple = 0;
  10. for (int i = Math.min(m, n); i >= 1; i--) {
  11. if (m % i == 0 && n % i == 0) {
  12. greatestCommonDivisor = i;
  13. break;
  14. }
  15. }
  16. for (int i = Math.max(m, n); i <= m * n; i++) {
  17. if (i % m == 0 && i % n == 0) {
  18. leastCommonMultiple = i;
  19. break;
  20. }
  21. }
  22. System.out.println("最大公约数:" + greatestCommonDivisor + "\n最小公倍数:" + leastCommonMultiple);
  23. }
  24. }

运行结果:

  1. 请输入第 1 个正整数:20
  2. 请输入第 2 个正整数:12
  3. 最大公约数:4
  4. 最小公倍数:60

水仙花数

所谓水仙花数是指一个 3 位数,其各个位上数字立方和等于其本身。

  1. class GetDaffodilsNumber {
  2. public static void main(String[] args) {
  3. for (int i = 100; i <= 999; i++) {
  4. int individual, ten, hundred;
  5. individual = i % 10;
  6. ten = i / 10 % 10;
  7. hundred = i / 100;
  8. if (Math.pow(individual, 3) + Math.pow(ten, 3) + Math.pow(hundred, 3) == i) {
  9. System.out.println("i = " + i);
  10. }
  11. }
  12. }
  13. }

运行结果:

  1. i = 153
  2. i = 370
  3. i = 371
  4. i = 407

while循环

①<init_statement>;
while (②<test_exp>) {
③<body_statement>;
④<alter_statement>;
} ①-→②-→③-→④-→②-→③-→④-→②-→③-→④-→……-→②

  1. 注意不要忘记声明迭代部分④<alter_statement>。否则将出现死循环;
  2. for循环和while循环都可以相互转换。
  3. 对于for循环,初始化声明①<init_statement>;中的变量是局部变量,而while循环的可以在循环体外部被访问。它们的初始化声明变量的作用域不一样。

遍历 0~100 以内的偶数

  1. class LoopStructureWhileTest {
  2. public static void main(String[] args) {
  3. int i = 0;
  4. while (i <= 100) {
  5. if (i % 2 == 0) {
  6. System.out.println("i = " + i);
  7. }
  8. i++;
  9. }
  10. }
  11. }

do-while循环

①<init_statement>;
do {
③<body_statement>;
④<alter_statement>;
} while (②<test_exp>); ①-→③-→④-→②-→③-→④-→②-→③-→④-→……-→② do-while循环至少执行一次循环体。

遍历 0~100 以内的偶数

  1. class LoopStructureDoWhileTest1 {
  2. public static void main(String[] args) {
  3. int i = 1;
  4. do {
  5. if (i % 2 == 0) {
  6. System.out.println("i = " + i);
  7. }
  8. i++;
  9. } while (i <= 100);
  10. }
  11. }

循环语句综合练习

从键盘读入个数不确定的整数,并判断读入的正数和负数的个数,输入为 0 时结束程序。

for

  1. class LoopStructureExercise {
  2. public static void main(String[] args) {
  3. Scanner scan = new Scanner(System.in);
  4. int num, positiveNum = 0, negativeNum = 0;
  5. for (; ; ) {
  6. System.out.print("请输入一个整数(以[0]退出):");
  7. num = scan.nextInt();
  8. if (num > 0) {
  9. positiveNum++;
  10. } else if (num < 0) {
  11. negativeNum++;
  12. } else {
  13. break;
  14. }
  15. }
  16. System.out.println("positiveNum = " + positiveNum);
  17. System.out.println("negativeNum = " + negativeNum);
  18. }
  19. }

运行结果:

  1. 请输入一个整数(以[0]退出):1
  2. 请输入一个整数(以[0]退出):2
  3. 请输入一个整数(以[0]退出):-4
  4. 请输入一个整数(以[0]退出):-6
  5. 请输入一个整数(以[0]退出):-7
  6. 请输入一个整数(以[0]退出):3
  7. 请输入一个整数(以[0]退出):0
  8. positiveNum = 3
  9. negativeNum = 3

while

  1. class LoopStructureExercise {
  2. public static void main(String[] args) {
  3. Scanner scan = new Scanner(System.in);
  4. int positiveNum = 0, negativeNum = 0;
  5. while (true) {
  6. System.out.print("请输入一个整数(以[0]退出):");
  7. int num = scan.nextInt();
  8. if (num > 0) {
  9. positiveNum++;
  10. } else if (num < 0) {
  11. negativeNum++;
  12. } else {
  13. break;
  14. }
  15. }
  16. System.out.println("positiveNum = " + positiveNum);
  17. System.out.println("negativeNum = " + negativeNum);
  18. }
  19. }

运行结果:

  1. 请输入一个整数(以[0]退出):1
  2. 请输入一个整数(以[0]退出):4
  3. 请输入一个整数(以[0]退出):2
  4. 请输入一个整数(以[0]退出):-7
  5. 请输入一个整数(以[0]退出):-5
  6. 请输入一个整数(以[0]退出):22
  7. 请输入一个整数(以[0]退出):4
  8. 请输入一个整数(以[0]退出):0
  9. positiveNum = 5
  10. negativeNum = 2

do-while

  1. class LoopStructureExercise3 {
  2. public static void main(String[] args) {
  3. Scanner scan = new Scanner(System.in);
  4. int positiveNum = 0, negativeNum = 0;
  5. do {
  6. System.out.print("请输入一个整数(以[0]退出):");
  7. int num = scan.nextInt();
  8. if (num > 0) {
  9. positiveNum++;
  10. } else if (num < 0) {
  11. negativeNum++;
  12. } else {
  13. break;
  14. }
  15. } while (true);
  16. System.out.println("positiveNum = " + positiveNum);
  17. System.out.println("negativeNum = " + negativeNum);
  18. }
  19. }

运行结果:

  1. 请输入一个整数(以[0]退出):1
  2. 请输入一个整数(以[0]退出):2
  3. 请输入一个整数(以[0]退出):3
  4. 请输入一个整数(以[0]退出):4
  5. 请输入一个整数(以[0]退出):-1
  6. 请输入一个整数(以[0]退出):-2
  7. 请输入一个整数(以[0]退出):0
  8. positiveNum = 4
  9. negativeNum = 2

嵌套循环

当内层循环的循环条件为false则跳出内层循环,才可结束外层的当次循环,开始下一次的循环; 设外层循环次数为m次,内层为n次,则内层循环体实际上需要执行m*n次。

打印输出“*”型的矩形

  1. class LoopNestingTest1 {
  2. public static void main(String[] args) {
  3. for (int raw = 1; raw <= 3; raw++) {
  4. for (int column = 1; column <= 6; column++) {
  5. System.out.print('*');
  6. }
  7. System.out.println();
  8. }
  9. }
  10. }

运行结果:

  1. ******
  2. ******
  3. ******

打印输出直立的“-”型直角三角形

  1. class LoopNestingTest2 {
  2. public static void main(String[] args) {
  3. for (int i = 1; i <= 5; i++) {
  4. for (int j = 1; j <= i; j++) {
  5. System.out.print('-');
  6. }
  7. System.out.println();
  8. }
  9. }
  10. }

运行结果

  1. -
  2. --
  3. ---
  4. ----
  5. -----

打印输出倒立的“·”型直角三角形

  1. class LoopNestingTest3 {
  2. public static void main(String[] args) {
  3. for (int i = 6; i >= 1; i--) {
  4. for (int j = 1; j <= i; j++) {
  5. System.out.print('·');
  6. }
  7. System.out.println();
  8. }
  9. }
  10. }

运行结果

  1. ······
  2. ·····
  3. ····
  4. ···
  5. ··
  6. ·

打印输出以下形状

  1. *
  2. * *
  3. * * *
  4. * * * *
  5. * * * * *
  6. * * * *
  7. * * *
  8. * *
  9. *

代码参考:

  1. class LoopNestingTest4 {
  2. public static void main(String[] args) {
  3. int width = 4;
  4. String mark = "* ", blank = " ";
  5. for (int i = 1; i <= width; i++) {
  6. for (int j = width - i + 1; j > 1; j--) {
  7. System.out.print(blank);
  8. }
  9. for (int k = 1; k <= i; k++) {
  10. System.out.print(mark);
  11. }
  12. System.out.println();
  13. }
  14. for (int i = width - 1; i >= 1; i--) {
  15. for (int k = 1; k <= width - i; k++) {
  16. System.out.print(blank);
  17. }
  18. for (int j = i; j >= 1; j--) {
  19. System.out.print(mark);
  20. }
  21. System.out.println();
  22. }
  23. }
  24. }

打印输出九九乘法表

  1. class ChineseMultiplicationTable {
  2. public static void main(String[] args) {
  3. for (int i = 1; i <= 9; i++) {
  4. for (int j = 1; j <= i; j++) {
  5. System.out.print(j + "×" + i + "=" + i * j);
  6. System.out.print((i == j) ? "" : "\t");
  7. }
  8. System.out.println();
  9. }
  10. }
  11. }

运行结果:

  1. 1×11
  2. 1×22 2×24
  3. 1×33 2×36 3×39
  4. 1×44 2×48 3×412 4×416
  5. 1×55 2×510 3×515 4×520 5×525
  6. 1×66 2×612 3×618 4×624 5×630 6×636
  7. 1×77 2×714 3×721 4×728 5×735 6×742 7×749
  8. 1×88 2×816 3×824 4×832 5×840 6×848 7×856 8×864
  9. 1×99 2×918 3×927 4×936 5×945 6×954 7×963 8×972 9×981

试除法判断 100 以内的所有质数

基本策略

  1. class GetPrimeNumber {
  2. public static void main(String[] args) {
  3. for (int i = 2; i <= 100; i++) { // 遍历自然数范围:[2,100]
  4. boolean isPrimeNumber = true;
  5. for (int j = 2; j <= i - 1; j++) {
  6. if (i % j == 0) {
  7. isPrimeNumber = false;
  8. }
  9. }
  10. System.out.print(isPrimeNumber ? i + "\t" : "");
  11. }
  12. }
  13. }

运行结果:

  1. 2357111317192329313741434753596167717379838997

优化方案

使用System.currentTimeMillis();获取一个`long型`时间戳,表示从 _1970-01-01 00:00:00 至此刻的毫秒数。 在程序执行前后两次调用这个语句,作差可求得程序运行历时。

  1. class GetPrimeNumber {
  2. /**
  3. * 质数:在大于 1 的自然数中,除了 1 和该数本身,无法被其他自然数整除的数。
  4. *
  5. * @implNote 从 n 开始(n>=2),对于每一个待检测的数 N,如果在范围 [n, N-1] 内,
  6. * 没有任何一个数可以将 N 整除,那么数字 N 就是质数;
  7. * 只要有一个可以将 N 整除,那么数字 N 就是合数。
  8. * <p>
  9. * 范围 [n, N-1] 可以进一步缩小至 [n, √N]:任何一个合数 M 都可以表示为 a×b,其中 a>=b。
  10. * 当 a==b 时,n、a、b 的跨度范围最小。
  11. */
  12. public static void main(String[] args) { // 程序的入口地址
  13. System.out.print("求质数:范围 2~");
  14. Scanner scan = new Scanner(System.in);
  15. int maximum = scan.nextInt(), primeCounter = 0;
  16. long begin = System.currentTimeMillis();
  17. for (int i = 2; i <= maximum; i++) { // 遍历自然数范围:[2, maximum]
  18. boolean isPrimeNumber = true; // 为每一个参与遍历的数初始化一个标识符:isPrimeNumber,默认是质数
  19. for (int j = 2; j <= Math.sqrt(i); j++) { // 若参与遍历的这个数是 N,需要从 2 开始比较。【优化二】缩减跨度范围
  20. if (i % j == 0) { // 取余,看是否除尽
  21. isPrimeNumber = false; // 可以被除了 1 和它本身的其他数整除 —— 不是质数
  22. break; // 【优化一】只要不是质数就跳出对这个数的循环判断
  23. }
  24. }
  25. if (isPrimeNumber) {
  26. primeCounter++; // 是质数 -> 给 primeCounter 加 1
  27. }
  28. }
  29. long end = System.currentTimeMillis();
  30. System.out.println("共计 " + primeCounter + " 个质数。"); // 【优化三】取消输出打印值的过程,只输出范围内的质数个数,提高效率
  31. System.out.println("耗时 (ms):" + (end - begin));
  32. }
  33. }

运行结果:

  1. 求质数:范围 210000000
  2. 共计 664579 个质数。
  3. 耗时 (ms):5422

求“完数”

  1. public class GetPerfectNumber {
  2. /**
  3. * 若一个数恰好等于其因子之和,则为 “完数” (6 = 1+2+3=1×2×3)
  4. * 注:
  5. * 因子:除去该数本身的其他约数
  6. */
  7. public static void main(String[] args) {
  8. for (int i = 1; i <= 1000; i++) {
  9. int factor = 0;
  10. for (int j = 1; j <= i / 2; j++) {
  11. if (i % j == 0) {
  12. factor += j;
  13. }
  14. }
  15. if (i == factor) {
  16. System.out.print("\t" + i);
  17. }
  18. }
  19. }
  20. }

运行结果:

  1. 6 28 496

特殊关键字的使用

关键字 使用范围 在循环结构中的作用
break switch-case结构、循环结构 结束当前循环
continue 循环结构 结束当次循环

breakcontinue默认只作用于内层的循环。通过在循环结构前加标识的方式可以作用于指定循环。

  • return关键字也可以用于结束循环,但主要用于对方法的结束。

break

  1. class BreakTest1 {
  2. public static void main(String[] args) {
  3. for (int i = 1; i <= 10; i++) {
  4. if (i % 4 == 0) {
  5. break;
  6. }
  7. System.out.print(" " + i);
  8. }
  9. }
  10. }

运行结果:

  1. 1 2 3

嵌套:

  1. class BreakTest2 {
  2. public static void main(String[] args) {
  3. for (int i = 1; i <= 4; i++) {
  4. for (int j = 1; j <= 10; j++) {
  5. if (j % 4 == 0) {
  6. break;
  7. }
  8. System.out.print(j);
  9. }
  10. System.out.println();
  11. }
  12. }
  13. }

运行结果:

  1. 123
  2. 123
  3. 123
  4. 123

加标识

  1. class BreakTest3 {
  2. public static void main(String[] args) {
  3. breakTest3:
  4. for (int i = 1; i <= 4; i++) {
  5. for (int j = 1; j <= 10; j++) {
  6. if (j % 4 == 0) {
  7. break breakTest3;
  8. }
  9. System.out.print(j);
  10. }
  11. System.out.println();
  12. }
  13. }
  14. }

运行结果:

  1. 123

continue

  1. class ContinueTest1 {
  2. public static void main(String[] args) {
  3. for (int i = 1; i <= 10; i++) {
  4. if (i % 4 == 0) {
  5. continue;
  6. }
  7. System.out.print(" " + i);
  8. }
  9. }
  10. }

运行结果:

  1. 1 2 3 5 6 7 9 10

嵌套

  1. class ContinueTest2 {
  2. public static void main(String[] args) {
  3. for (int i = 1; i <= 4; i++) {
  4. for (int j = 1; j <= 10; j++) {
  5. if (j % 4 == 0) {
  6. continue;
  7. }
  8. System.out.print(j);
  9. }
  10. System.out.println();
  11. }
  12. }
  13. }

运行结果:

  1. 123567910
  2. 123567910
  3. 123567910
  4. 123567910

加标识

  1. class ContinueTest3 {
  2. public static void main(String[] args) {
  3. continueTest3:
  4. for (int i = 1; i <= 4; i++) {
  5. for (int j = 1; j <= 10; j++) {
  6. if (j % 4 == 0) {
  7. continue continueTest3;
  8. }
  9. System.out.print(j);
  10. }
  11. System.out.println();
  12. }
  13. }
  14. }

运行结果:

  1. 123123123123

试除法判断质数(改进)

  1. class GetPrimeNumberPro {
  2. public static void main(String[] args) {
  3. System.out.print("求质数:范围 2~");
  4. Scanner scan = new Scanner(System.in);
  5. int maximum = scan.nextInt(), primeCounter = 0;
  6. long begin = System.currentTimeMillis();
  7. loopTest:
  8. for (int i = 2; i <= maximum; i++) {
  9. for (int j = 2; j <= Math.sqrt(i); j++) {
  10. if (i % j == 0) {
  11. continue loopTest; // 不是质数,直接测试下一个数
  12. }
  13. }
  14. primeCounter++; // 只有是质数的时候才 +1
  15. }
  16. long end = System.currentTimeMillis();
  17. System.out.println("共计 " + primeCounter + " 个质数。");
  18. System.out.println("耗时 (ms):" + (end - begin));
  19. }
  20. }