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
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 */
-