4. 控制执行流程
4.1 true and false
所有条件语句都利用条件表达式的真假来决定执行路径
4.2 if-else
-
结构
if(Boolean expression) statement else if(Boolean expression) statement else statement
4.3 迭代
-
结构
while(Boolean expression) statement
-
规则
- 在循环刚开始时会计算一次,下一次迭代开始前会再计算一次,直到得到“假”的结果
-
Test
package one; import static util.StaticPrint.*; public class TestIteration {static boolean condition(){boolean res = Math.random() < 0.99 ; print(res+""); return res; } public static void main(String[] args) {while (condition()){print("inside"); } print("exite"); } }
4.3.1 do-while
-
结构
do statement while(Boolean expression)
-
规则
- 先执行 statement,然后进行判断
- 相比于 while,区别是 do-while 循环至少会执行一次 statement
- while 使用率高于 do-while
4.3.2 for
-
结构
label: for(initialization;Boolean expression;step) statement
-
规则
- initialization;Boolean expression;step 都可以为空
- initialization 仅首次生效
- 迭代先执行 Boolean expression,true 后执行 statement,再执行 step,此为一个循环;
- break 是终止当前所在循环,continue 是终止本次循环,重新进行下一次循环
- 循环中的 label 标签,使得在循环嵌套中,break 和 continue 退出到指定的循环,见 Test
-
Test
<!– 使用循环嵌套和 label 标签实现输出 100 以内的素数 –>
package four; import static util.StaticPrint.*; public class PrimeNumber {public static void main(String[] args) {outer:for (int i = 1 ; i < 100 ; i++){inter:for (int j = 2 ; j < i ; j++){if ( i%j == 0){ // 退出到指定的循环 continue outer; } } print(i+""); } } }
4.3.3 逗号操作符
-
结构
for(int i = 1, j = 2 ; ;) statement
-
规则
- 仅在 for 循环的 initialization 中支持定义多个变量
- 变量的类型需要保持一致
4.4 Foreach 语法
-
结构
for(type param : params) statement
-
规则
- 定义了 type 类型的变量 param,然后将每一个 params 中的元素赋值给 param
-
Test
package five; import static util.StaticPrintnb.*; public class TestForeach {public static void main(String[] args) {for (char c:"You konw what I mean".toCharArray() ) {printnb(c+""); } } }
4.5 Reuturn
-
用途
- 指定返回值
- 导致当前方法退出,并返回值;如果是多重循环,能够直接退出整个循环
-
规则
- 如果一个方法声明它将返回 void 之外的内容,必须确保每个代码路径都有返回值
-
Test
<!– 直接退出三层循环 –>
package seven; public class TestReturn {public static void main(String[] args) {for(;;){for (;;){for (int i = 0 ; i < 100 ; i++){System.out.println(i); return; } } } } }
4.6 break and continue
4.6.1 Break
-
规则
- 强行退出循环,不执行循环中剩余的语句
- 不执行递增表达式,因此需要手动 ++
-
GOTO 用法
- 使用 break label,能够从任意循环终止指定的循环
4.6.2 Continue
-
规则
- 停止执行当前迭代,退出到循环起始点
- 不执行递增表达式,因此需要手动 ++
-
GOTO 用法
- 使用 continue label,能够跳跃到任意循环的起始点
-
Test
package four; import static util.StaticPrint.*; public class PrimeNumber {public static void main(String[] args) {outer:for (int i = 1 ; i < 100 ; i++){inter:for (int j = 2 ; j < i ; j++){if ( i%j == 0){ // 退出到指定的循环 continue outer; } } print(i+""); } } }
4.8 Switch
- 简介
switch 为选择语句
-
结构
switch(integral-selector){ case integral-value1:statement;break; case integral-value2:statement;break; case integral-value3:statement;break; case integral-value4:statement;break; default:statement; }
-
规则
- integral-selector 和 integral-value 的值必须为 int 或 char 类型
- 匹配成功后,如果没有 break 会继续执行,直到遇到 break 或者 default,因此后续所有值都会输出
- case 语句块中没有 break 语句时,JVM 并不会顺序输出每一个 case 对应的返回值,而是继续匹配,匹配不成功则返回默认 case
-
Test
public class RunSwitch {public static void main(String[] args) { int i = 2; switch (i){ case 0: System.out.println(0); case 1: System.out.println(1); case 2: System.out.println(2); case 3: System.out.println(3); } } }/* output 2 3 */
4.9 Practice
吸血鬼算法
- 题目
吸血鬼数字是指位数为偶数的数字,可以由一堆数字想乘而得到。而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个 0 结尾的数字是不允许的,例如,下列的数字都是“吸血鬼”数字:
1260=21*60
1827=21*87
2187=27*81
写出一个程序,找出 4 位数的所有吸血鬼数字
-
思路
-
个人思路
- 使用两位数的循环相乘得出四位数
- 将两个两位数和四位数分别拆成单个字符,保存在 List 中
- 使用 List 的 equals 方法判断是否相等
-
官方思路
- 遍历所有四位数
- 将四位数拆分并分别组合成两个两位数,一共有 12 种搭配方式
- 每一种搭配方式都判断
-
优势
- 个人思路能够减少近一半的遍历次数,约 3000 次
-
-
实现
-
个人思路
package ten; import java.util.*; public class VampireNumberImp {static int VampireJudgeImp(){List<Integer> VampireArray = new ArrayList<Integer>(); List<Character> ikList = new ArrayList<Character>(); List<Character> sumList = new ArrayList<Character>(); int point = 0; for (int i = 11 ; i < 100 ; i++){for (int k = i ; k < 100 ; k++){ int sum = i * k; // 判断是否为四位数, 判断是否为两个零结尾 if (sum < 1000 || sum > 9999 || sum % 100 == 0 || VampireArray.contains(sum)){continue;} point++; // 判断是否为吸血鬼数字 // 将数字添加进 list ikList.add((char) (i / 10)); ikList.add((char) (i % 10)); ikList.add((char) (k / 10)); ikList.add((char) (k % 10)); sumList.add((char) (sum / 1000)); sumList.add((char) (sum % 1000 / 100)); sumList.add((char) (sum % 1000 % 100 / 10)); sumList.add((char) (sum % 10)); // 数字排序 Collections.sort(ikList); Collections.sort(sumList); // 判断是否为吸血鬼数字 if (ikList.equals(sumList)){VampireArray.add(sum); System.out.println(sum); } ikList.clear(); sumList.clear();} } return point; } public static void main(String[] args) {long startTime=System.currentTimeMillis(); int point = VampireJudgeImp(); // 测试代码执行时间 long endTime=System.currentTimeMillis(); System.out.println("程序运行时间:"+(endTime - startTime)+"ms"); System.out.println("程序运行次数:"+point+"次"); } }/* output 1395 1260 1827 2187 1530 1435 6880 程序运行时间:19ms 程序运行次数:3210 次 */
-
官方思路
package ten; public class VampireNumberOfficial {static int a(int i) {return i/1000;} static int b(int i) {return (i%1000)/100; } static int c(int i) {return ((i%1000)%100)/10; } static int d(int i) {return ((i%1000)%100)%10; } static int com(int i, int j) {return (i * 10) + j; } static void productTest (int i, int m, int n) {if(m * n == i) System.out.println(i + "=" + m + "*" + n); } public static void main(String[] args) {long startTime=System.currentTimeMillis(); for(int i = 1001; i < 9999; i++) {productTest(i, com(a(i), b(i)), com(c(i), d(i))); productTest(i, com(a(i), b(i)), com(d(i), c(i))); productTest(i, com(a(i), c(i)), com(b(i), d(i))); productTest(i, com(a(i), c(i)), com(d(i), b(i))); productTest(i, com(a(i), d(i)), com(b(i), c(i))); productTest(i, com(a(i), d(i)), com(c(i), b(i))); productTest(i, com(b(i), a(i)), com(c(i), d(i))); productTest(i, com(b(i), a(i)), com(d(i), c(i))); productTest(i, com(b(i), c(i)), com(d(i), a(i))); productTest(i, com(b(i), d(i)), com(c(i), a(i))); productTest(i, com(c(i), a(i)), com(d(i), b(i))); productTest(i, com(c(i), b(i)), com(d(i), a(i))); } long endTime=System.currentTimeMillis(); System.out.println("程序运行时间:"+(endTime - startTime)+"ms"); } }/*output 1260 = 21 * 60 1395 = 15 * 93 1435 = 41 * 35 1530 = 51 * 30 1827 = 87 * 21 2187 = 27 * 81 6880 = 86 * 80 6880 = 80 * 86 程序运行时间:54ms */
-