Thinking in Java

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

  • 用途

    1. 指定返回值
    2. 导致当前方法退出,并返回值;如果是多重循环,能够直接退出整个循环
  • 规则

    • 如果一个方法声明它将返回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位数的所有吸血鬼数字

  • 思路

    • 个人思路
      1. 使用两位数的循环相乘得出四位数
      2. 将两个两位数和四位数分别拆成单个字符,保存在List中
      3. 使用List的equals方法判断是否相等
    • 官方思路
      1. 遍历所有四位数
      2. 将四位数拆分并分别组合成两个两位数,一共有12种搭配方式
      3. 每一种搭配方式都判断
    • 优势
      1. 个人思路能够减少近一半的遍历次数,约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
      */
      
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容