本文纲要:

为什么须要流程管制

平时咱们做一件事,个别都会有个固定流程

比方你想吃苹果,你须要找到冰箱,关上冰箱门,取出苹果,回到沙发上,而后开吃。

这个程序根本不能调换,你不能在关上冰箱门之前去取苹果。按程序来管制,这是一种流程。

那如果你想吃香蕉,你会发现流程相似,只是从冰箱里取出香蕉就好了。

在这个过程里,你会发现你最终吃什么,取决于你的抉择。你要吃苹果,你从冰箱里取苹果,你要吃香蕉,你从冰箱里取香蕉。按抉择来管制,这也是一种流程。

那还有种状况,一根香蕉不够你吃,你还想吃几根,直到你不想吃,那你就会反复下面的流程,当你吃饱的时候,就终止了。这种反复执行依照某个条件来终止的管制,也是一种流程。

计算机是事实世界的电子化表白,那么在计算机的世界里,程序运行也须要这样的流程管制

无论是机器语言,还是汇编语言,还是高级程序设计语言,都会波及这个概念,它决定了你写的代码会依照怎么的门路运行,也决定着计算机和用户之间的交互方式

咱们看看 Java 语言的流程管制是什么样的?

输出和输入

咱们编程都是为了解决某个理论问题,比方写一个加法程序,咱们是为了取得两个数的和是多少。

那你会发现,程序有个重要的特点,就是接管输出,而后进行解决,最初输入后果

那 Java 是怎么接管输出的呢?

Scanner 介绍

Java 提供了 Scanner 工具类,咱们能够通过这个工具类来获取用户的输出。根本的语法如下:

// 用规范的输出流构建一个 Scanner 对象Scanner scanner = new Scanner(System.in);// 读取输出的一行并获取字符串String nextLineStr = scanner.nextLine();// 读取输出的字符串,会疏忽掉字符串两边的空格,因为空格起分隔符或结束符的作用String nextStr = scanner.next();// 读取输出的整数,非整数会抛异样(InputMismatchException)int nextInt = scanner.nextInt();

System.in 是规范的输出流,应用它能够接管键盘输入或其余指定数据源的数据。

Scanner 是一个简略的文本扫描器,通过它能够解析根本类型和字符串。new Scanner(System.in) 能够构建出一个扫描器对象,scanner.nextLine()能够读取输出的一行并获取字符串,scanner.next() 也能够获取字符串,不过不能反对两边有空格的字符串,scanner.nextInt() 能够读取输出的整数,int 换成其余根本类型同样也实用。

Scanner 应用

咱们能够看下样例代码:

package cn.java4u.flowcontrol;import java.util.Scanner;/** * 输出演示 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class InputDemo {    public static void main(String[] args) {        // 用规范的输出流构建一个 Scanner 对象        Scanner scanner = new Scanner(System.in);        // 读取输出的一行并获取字符串        String nextLineStr = scanner.nextLine();        // 读取输出的字符串,会疏忽掉字符串两边的空格,因为空格起分隔符或结束符的作用        String nextStr = scanner.next();        // 读取输出的整数,非整数会抛异样(InputMismatchException)        int nextInt = scanner.nextInt();        System.out.println("---以下为打印值---");        System.out.println("nextLineStr:" + nextLineStr);        System.out.println("nextStr:" + nextStr);        System.out.println("nextInt:" + nextInt);    }}

你会发现,样例代码里有一个 import java.util.Scanner; ,Scanner 是 Java 类库里的一个类,所以须要 import 语法引入一下,能力应用。

样例代码有三次控制台输出,咱们输出以下数据看下输入:

我是蜗牛      蜗牛666    8

第一行输出的字符串后边有空格,第二行输出的字符串前后都有空格。输入如下:

---以下为打印值---nextLineStr:我是蜗牛   nextStr:蜗牛666nextInt:8

你会发现 nextLineStr 后边的空格还在,nextStr 前后的空格都没有了。

咱们再看一种输出:

我是蜗牛      蜗牛666  7

当咱们输出两行后,再回车,程序就间接输入后果了:

nextLineStr:我是蜗牛   nextStr:蜗牛666nextInt:7

由此可见 nextLine()next() 之间的不同,nextInt()next() 根底上的类型转换,特点能够认为和 next() 统一。

起始符分隔符特点
nextLine()任何字符回车(Enter)能够取得带空格的字符串
next()非空白字符空格不能取得带空格的字符串

输入

在之前的代码中,咱们都是通过 System.out.println() 的形式,把内容输入到控制台的。

其中 System.out 是规范的输入流,通过它不只能够做显示输入,也能够写入到指定的输入指标,比方文件。

println 是 print line 的缩写,示意输入并换行。如果输入不想换行,能够应用 print() 。此外,Java 也反对用 printf() 进行格式化输入,以不便浏览。

以下是示例代码:

package cn.java4u.flowcontrol;/** * 输入演示 * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class OutputDemo {    public static void main(String[] args) {        // 输入并换行        System.out.println("---开始演示---");        // 输入不换行        System.out.print("打印不换行[");        System.out.print("1 ");        System.out.print("2 ");        System.out.print("3");        System.out.print("]");        // 只换行        System.out.println();        // 格式化输入        double d = 66600000.8888;        // 不进行格式化的处理结果:6.66000008888E7        System.out.println("不进行格式化的处理结果:" + d);        System.out.printf("默认格式化:%f", d);        System.out.printf("; 无小数格式化:%.0f", d);        System.out.printf("; 一位小数格式化:%.1f", d);        System.out.printf("; 两位小数格式化:%.2f", d);    }}

输入后果如下:

---开始演示---打印不换行[1 2 3]不进行格式化的处理结果:6.66000008888E7默认格式化:66600000.888800; 无小数格式化:66600001; 一位小数格式化:66600000.9; 两位小数格式化:66600000.89

%f 就是 Java 为浮点数提供的格式化性能的占位符,零碎默认会把浮点数格式化成 6 位小数输入,当然你也能够仿照样例指定小数位输入。

除了浮点数,Java 的格式化性能还提供了多种占位符,能够把各种数据类型格式化成指定的字符串,以下是罕用的占位符:

占位符阐明
%d格式化输入整数
%x格式化输入十六进制整数
%f格式化输入浮点数
%e格式化输入迷信计数法示意的浮点数
%s格式化字符串

留神,因为 % 示意占位符,因而,间断两个 %% 示意一个 % 字符自身。

三种流程控制结构

晓得了输出和输入在 Java 世界里的表达方式,咱们再看下在程序处理中波及到的流程管制有哪些。

程序构造

程序根本的流程构造就是程序构造,Java 也是如此。如果没有特地指明,程序都是依照程序一行一行执行。

抉择构造

但很多时候,咱们须要判断一个货色是否可行,而后才去执行一段逻辑。比方加法程序,咱们得要求参加运算的值是数字而不能是字符串。

那这样的流程管制能够通过抉择构造来实现。

if单抉择构造

如果只是想针对某个条件非凡解决下,解决前后的逻辑不变,此时能够应用if单抉择构造。

语法如下:

if(布尔表达式){ //布尔表达式后果为 true 时执行的语句}

以下是打印两个整数的最大值的示例代码:

package cn.java4u.flowcontrol;import java.util.Scanner;/** * if 单抉择构造 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class IfSingleChoiceDemo {    public static void main(String[] args) {        // 用规范的输出流构建一个 Scanner 对象        Scanner scanner = new Scanner(System.in);        System.out.println("请输出整数a:");        int a = scanner.nextInt();        System.out.println("请输出整数b:");        int b = scanner.nextInt();        // 初始化最大值为 a 的值        int max = a;        // b 比 a 大的申请下,把 b 的值赋给 max        if (a < b) {            max = b;        }        System.out.println("max:" + max);    }}

咱们用数字 a 初始化了变量 max,只有发现 b 比 a 大的时候,才会把 b 的值赋给 max。也就是 当 a=10 并且 b=9 时,if 花括号里的逻辑是走不到的,当 a=10 并且 b=11 时,if 花括号里的逻辑会走到。

if双抉择构造

有时候咱们遇到某个条件,会有两种不同的逻辑,此时能够应用if双抉择构造。

语法如下:

if(布尔表达式){ //布尔表达式后果为 true 时执行的语句}else{ //布尔表达式后果为 false 时执行的语句}

以下是打印整数绝对值的示例代码:

package cn.java4u.flowcontrol;import java.util.Scanner;/** * if双抉择构造 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class IfDoubleChoiceDemo {    public static void main(String[] args) {        // 用规范的输出流构建一个 Scanner 对象        Scanner scanner = new Scanner(System.in);        System.out.println("请输出整数a:");        //10,-10 切换        int a = scanner.nextInt();        // 初始化绝对值变量        int abs;        if (a < 0) {            abs = -a;        } else {            abs = a;        }        System.out.println("abs:" + abs);    }}

咱们用 abs 初始化了绝对值变量,针对待断定的整数 a,当它的值是 10 或者 -10 时,会走 if 的不同分支执行不一样的逻辑。

if多抉择构造

当咱们遇到的条件不只一个的时候,咱们执行逻辑的状况可能会超过两个,此时能够应用if多抉择构造。

语法如下:

if(布尔表达式1){ //布尔表达式1后果为 true 时执行的语句}else if(布尔表达式2){ //布尔表达式2后果为 true 时执行的语句}    else{ //布尔表达式后果为 false 时执行的语句}

以下是百分制问题评低劣差的示例代码:

package cn.java4u.flowcontrol;import java.util.Scanner;/** * if 多抉择构造 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class IfMultiChoiceDemo {    public static void main(String[] args) {        // 用规范的输出流构建一个 Scanner 对象        Scanner scanner = new Scanner(System.in);        System.out.println("请输出你的问题(百分制):");        //58,68,88,96,120 切换        int score = scanner.nextInt();        if (score > 0 && score < 60) {            System.out.println("不合格");        } else if (score >= 60 && score < 80) {            System.out.println("合格");        } else if (score >= 80 && score < 90) {            System.out.println("良好");        } else if (score >= 90 && score <= 100) {            System.out.println("优良");        } else {            System.out.println("非法输出");        }    }}

问题分数评低劣差的程序存在区间多级判断,比拟适宜if多抉择构造。

if嵌套抉择构造

当咱们遇到的条件里,又能拆出多个条件,有不同的执行逻辑时,能够应用if嵌套抉择构造。if嵌套抉择构造能够认为是if多抉择构造的变种。

语法如下:

if(布尔表达式1){ //布尔表达式1后果为 true 时执行的语句        if(布尔表达式2){        //布尔表达式2后果为 true 时执行的语句    }}

以下是百分制问题评低劣差变形后的示例代码:

package cn.java4u.flowcontrol;import java.util.Scanner;/** * if嵌套抉择构造 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class IfNestChoiceDemo {    public static void main(String[] args) {        // 用规范的输出流构建一个 Scanner 对象        Scanner scanner = new Scanner(System.in);        System.out.println("请输出你的问题(百分制):");        //58,68,88,96,120 切换        int score = scanner.nextInt();        if (score >= 0 && score <= 100) {            if (score < 60) {                System.out.println("不合格");            } else if (score < 80) {                System.out.println("合格");            } else if (score < 90) {                System.out.println("良好");            } else {                System.out.println("优良");            }        } else {            System.out.println("非法输出");        }    }}

和一般的 if多抉择构造 的代码不同在于,if嵌套抉择做了两层抉择,第一层是输出的合法性,第二层是对问题做分级。

switch抉择构造

咱们有时候遇到的条件比拟无限,并且就是判断一个变量与一系列中某个值是否相等,而后命中不同的值,会走向不同的逻辑。此时就能够应用switch抉择构造。

语法如下:

switch(var){    case value1:        // var 命中 value1 时执行的语句        break;    case value2:        // var 命中 value2 时执行的语句        break;    //能够有任意数量的case语句    // 默认的申请,上边都没命中,会走到该分支    default:        //以上 case 都未命中或者未 break 会走到这里}

咱们如果把上边提到的几个程序打包给用户应用,那就能够通过 switch 来提供对立的入口,疏导用户键入1来路由到求最大值的程序里,键入2路由到求绝对值的程序里,键入3路由到问题分数评低劣差的程序里。示例代码如下:

package cn.java4u.flowcontrol;import java.util.Scanner;/** * switch抉择构造 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class IfSwitchChoiceDemo {    public static void main(String[] args) {        // 用规范的输出流构建一个 Scanner 对象        Scanner scanner = new Scanner(System.in);        System.out.println("请抉择你要运行的程序(键入1示意求最大值,键入2示意求绝对值,键入3示意问题分数评低劣差):");        int choice = scanner.nextInt();        switch (choice) {            case 1:                System.out.println("--开始求两个数的最大值--");                IfSingleChoiceDemo.main(null);                break;            case 2:                System.out.println("--开始求绝对值--");                IfDoubleChoiceDemo.main(null);                break;            case 3:                System.out.println("--开始问题分数评低劣差--");                IfMultiChoiceDemo.main(null);                break;            default:                System.out.println("非法输出");        }    }}

跑一下这个程序,键入 1 你会发现开始执行求最大值的子程序里,最大值打印后整个程序就完结了,这阐明 break 起到了以后分支阻断程序的作用。一旦命中 break 代码,后边的 case 2case 3default 都不会走到。

当然不是每个 case 都须要有 break 的,当你有两个 case 的逻辑统一,就能够疏忽 break 进行 case 合并,比方当键入 4 的时候,我要求和 3 成果统一,能够改成上面这样:

case 3:case 4:    System.out.println("--开始问题分数评低劣差--");    IfMultiChoiceDemo.main(null);    break;

没有 break 的 case 逻辑会穿透到下一个 case,应用下一个 case 的代码逻辑。

留神,switch抉择构造是if多抉择构造非凡场景下的变种,JavaSE 8 反对的变量类型有 byte、short、int、char、String、ENUM

循环构造

程序有时候会反复运行一段逻辑,如果按程序构造+抉择构造来组织代码的话,这种状况下须要写很多反复的代码能力实现。比方我要失去从 1 到 5 的和:

1+2+3+4+5=?

我的代码可能就是这样:

package cn.java4u.flowcontrol;/** * while 循环构造演示 * * @author 蜗牛 * @from 公众号:蜗牛互联网 */public class WhileCircleDemo {    public static void main(String[] args) {        int a = 1;        int sum = 0;        System.out.println("以后a的值为:" + a);        // a 累加到 sum 中        sum = sum + a;        // a 本身加一        a = a + 1;        System.out.println("以后a的值为:" + a);        sum = sum + a;        a = a + 1;        System.out.println("以后a的值为:" + a);        sum = sum + a;        a = a + 1;        System.out.println("以后a的值为:" + a);        sum = sum + a;        a = a + 1;        System.out.println("以后a的值为:" + a);        sum = sum + a;                System.out.println("sum:" + sum);    }}

你会发现反复逻辑很多,在 a = 5 的时候,累加才完结,后果才输入。那如果有种机制能把这些反复的逻辑用简洁的形式表白,那写代码就会不便很多。

这种机制就是循环构造。

while循环构造

最罕用的循环构造是 while 循环,语法如下:

while(布尔表达式){ //循环内容}
  • 只有布尔表达式为 true,循环就会始终执行上来。
  • 咱们大多数状况是会让循环停止下来的,因而须要一个让布尔表达式为 false 的形式来进行循环。
  • 少部分状况时须要循环始终执行,比方服务器的申请响应监听等。
  • 循环条件如果始终是 true,就会造成有限循环,应尽量避免这种状况,否则会造成程序卡死解体。

用 while 来表白求和代码如下:

// 初始化值a = 1;sum = 0;while (a <= 5) {    // a 累加到 sum 中    sum += a;    // a 本身加一    a++;}System.out.println("while sum:" + sum);

do while循环构造

察看 while 语句,你会发现,只有不满足条件,就不能进入循环。但有时候咱们须要即便不满足条件,也至多要执行一次。那此时用 do while 循环就比拟适合,语法如下:

do{ //循环内容}where(布尔表达式)
  • 不同于 while 循环构造的先判断后执行的形式,do while 循环构造是先执行后判断
  • do while 中的循环内容会被至多执行一次

用 do while 来表白求和代码如下:

// 初始化值a = 1;sum = 0;do {    // a 累加到 sum 中    sum += a;    // a 本身加一    a++;} while (a <= 5);System.out.println("do while sum:" + sum);

for循环构造

在求和代码中,咱们会发现,a 就像一个计数器,通过 a = 1 初始化一个值,而后在每次循环中加一来当成咱们求和时要加的那个数,a <= 5 作为计数器循环检测条件,决定了咱们的累加是加到 5 还是 100,只有改成 a <= 100,累加到 100 就不会再执行循环。

这种其实是迭代解决的通用构造:初始值、终止条件和计数器。于是 Java 提供了 for 循环构造,用来简化这种场景下的 while 循环,语法如下:

for(计数器初始化; 布尔表达式; 循环后更新计数器){ //循环内容}

用 for 来表白求和代码如下:

sum = 0;for (a = 1; a <= 5; a++) {    sum += a;}System.out.println("for sum:" + sum);

for each循环构造

有些时候,咱们拿到一堆数解决,其实并不关怀他们的秩序,只有能遍历到就能够。比方数组里的几个值,我不关怀值的索引,我只想晓得这些值的总和是多少。此时就能够用 for each 循环构造,它能够很简略的遍历数组,语法如下:

for(元素类型 元素变量 : 数组或迭代器){ //循环内容}
  • for each 是对 for 非凡场景下的简化,解决对象是数组或者迭代器对象
  • 和 for 循环构造相比,for each 循环构造不再体现计数器的初始化和更新,因而也无奈指定遍历程序,也不能获取数组或迭代器索引

用 for each 来表白求和代码如下:

int[] array = {1, 2, 3, 4, 5};sum = 0;for (int temp : array) {    sum += temp;}System.out.println("for each sum:" + sum);

循环构造的中断

循环构造都会有个布尔表达式作为循环检测条件,如果布尔表达式为 false 时,就会终止循环,这是循环中断的一种形式。

除此之外,Java 还提供了另外两种循环构造中断的形式。

一种是 break。语法如下:

循环构造{    //中断前代码    if(中断布尔表达式){  break;    }    //中断后代码}
  • 中断布尔表达式返回 true 时,命中 break ,间接退出整个循环构造,中断后代码不再执行。

求和示例代码如下:

int a = 1;int sum = 0;while (a <= 5) {    // a 为 3 的时候中断    if (a == 3) {        break;    }    // a 累加到 sum 中    sum += a;    // a 本身加一    a++;}System.out.println("while sum:" + sum);
  • 理论对 1 和 2 进行求和,因为 a 为 3 的时候退出了循环。

留神:循环构造如果存在嵌套,break 只会退出以后层循环构造,不会退出外层循环构造。

另一种是 continue,语法如下:

循环构造{    //中断前代码    if(中断布尔表达式){  continue;    }    //中断后代码}
  • 中断布尔表达式返回 true 时,命中 continue ,该循环构造当次调用中断,中断后代码当次不再执行,进入循环构造的下次调用。

示例代码如下:

int i = 0;while (i <= 5) {    i++;    // i 为 3 的时候中断    if (i == 3) {        System.out.println("命中 continue");        continue;    }    System.out.println("i=" + i);}

输入:

i=1i=2命中 continuei=4i=5i=6

会发现 i 的值为 3 的时候命中 continue 逻辑,当次循环不会持续往下走,但会进入下一次循环。

简略讲,break 跳出以后层循环循环构造停止continue 跳出当次循环调用当次调用停止。二者都要配合 if 应用。

小结

本文从事实案例引出了流程管制的概念,映射到编程畛域,咱们把一个程序的执行,形象成输出-解决-输入的过程。而后介绍了在 Java 的世界里,输出和输入的实现形式,接着解说了在解决的过程中,罕用的三种流程控制结构:程序构造、抉择构造和循环构造,并列出了演示代码。读者能够仿照案例实际一把,置信你会有更粗浅的印象。感激你的浏览和分享,欢送留言互动和点赞!


我是蜗牛,大厂程序员,专一技术原创和个人成长,正在互联网上摸爬滚打。欢送关注我,和蜗牛一起成长,咱们一起牛~下期见!