Java开发笔记(二十二)神奇的冒号

时间:2022-08-13 23:09:23

Java中的标点符号主要有两类用途,一类是运算符,包括加号+、减号-、乘号*、除号/、取余号%、等号=、大于号>、小于号<、与号&、或号|、非号!、异或号^等等,另一类则是分隔符,包括区分代码块的花括号{}、容纳特定语句的圆括号()、标明数组元素的方括号[]、分隔长句的分号、分隔短句的逗号、分隔包名类名方法名的点号等等。当然还有几个特殊的分隔符,比如三元运算符“?:”,它的完整形式为“A?:B:C”,当式子A成立时,得到式子B的结果,不成立时得到式子C的结果。这些标点符号之中,尤以冒号最为特殊,之所以这么说,是因为Java编程一遇到特殊的分隔场景,基本都拿冒号这个万金油做标记。

冒号除了用在三元运算符“?:”以外,至少还有其它三种用法。第二种是在多路分支的时候,犹记得当年switch-case并肩作战,每个case带着数值再拖上具体的处理语句,case条件与处理语句之间可是以冒号分隔的,剩余的默认情况default也是通过冒号同处理语句区分开。譬如下面的多路分支代码,就能看到冒号的分隔作用:

		// switch允许判断某个变量的多个取值,并分别进行单独处理
switch (seq) {
case 1: // seq值为1时进入该分支
System.out.println("凉风有信的谜底是“讽”");
break; // 跳出多路分支。即跳到switch分支的右花括号之后
case 2: // seq值为2时进入该分支
System.out.println("秋月无边的谜底是“二”");
break; // 跳出多路分支。即跳到switch分支的右花括号之后
default: // seq值为其它时进入该分支
System.out.println("您的按键有误");
break; // 跳出多路分支。即跳到switch分支的右花括号之后
}

冒号的第三种用法,则跟数组的循环遍历有关。要想把某个数组里的所有元素数值都打印出来,就得通过for循环依次取出数组的每个元素,再打印该元素的数值。以整型数组为例,利用for语句遍历并打印元素的代码如下所示:

		int[] primeNumbers = {2, 3, 5, 7};
for (int i = 0; i < primeNumbers.length; i++) {
int number = primeNumbers[i]; // 获取下标为i的元素,并赋值给名为number的变量
System.out.println("prime number = " + number);
}

上面的循环语句很常规,用法形式也很常见,无非是依次取出数组里的每个元素罢了。倘若此时不修改元素数值,仅仅是读取数值的话,那么可以简化成一套通用的循环模板,就像下述的循环语句那样:

		int[] primeNumbers = {2, 3, 5, 7};
// 在for循环中,可以利用“变量类型 变量名称 : 数组名称”的形式,直接把数组元素赋值给该变量
for (int number : primeNumbers) {
System.out.println("number = "+number);
}

上述的Java代码,把原循环内部的变量number提前放到for后面的圆括号当中,并且number与数组primeNumbers之间用冒号分开,表示每次循环处理之前,都把数组元素逐个赋值给number变量,然后循环内部即可直接处理该变量。如此这般便优化了先前的for循环代码,免去了冗余的数组下标、判断条件以及自增操作。

冒号的第四种用法也与循环语句有关,但不限于for循环,而是与for和while都有关联。前述的循环处理,基本都只有一层循环,然而实际开发常常会遇到多层循环,也就是一个循环内部嵌套了另一个循环,看起来像是层峦叠嶂、反复重叠,故又被称作多重循环。例如有个二维数组,要把它里面的所有元素都打印出来,这便需要两层循环才能搞定,第一层循环负责遍历第一个维度的下标,而第二层循环负责遍历第二个维度的下标,编码上则需一个for循环嵌套另一个for循环,具体的Java实现代码如下所示:

		double[][] triangle = { {-2.0, 0.0}, {0.0, -1.0}, {2.0, 1.0} };
// 下面通过多重循环依次打印二维数组里面的所有元素
for (int i=0; i<triangle.length; i++) {
for (int j=0; j<triangle[i].length; j++) {
System.out.println("value = "+triangle[i][j]);
}
}

可见以上的多重循环代码还是挺简单的,并不涉及到复杂的break和continue操作。即使用到break和continue,处理逻辑也没有什么特别之处,因为break语句想当然就是只能跳出当前层次的循环,不能跳出上个层次的循环,continue语句同理。所以要想从内层循环跳出外层循环,就得设置一个标记,从内层循环跳到外层循环时,通过判断该标记再决定是否立刻跳出外层循环。仍以前面的二维数组为例,假设在内层循环找到某个元素为0.0,则立即结束全部循环(包括外层循环和内层循环),按此思路编写的代码例子见下:

		// 下面的循环要求:一旦发现数组元素等于0.0,就立即从第二层循环跳出第一层循环(跳出两层循环)
for (int i=0; i<triangle.length; i++) {
boolean isFound = false; // 该布尔变量用来标记是否找到0.0
for (int j=0; j<triangle[i].length; j++) {
if (triangle[i][j] == 0.0) {
isFound = true; // 找到了0.0
System.out.println("simple found 0.0");
break; // 跳出第二层循环
}
}
if (isFound) {
break; // 跳出第一层循环
}
}

以上代码固然实现了功能要求,但是两个break的写法着实令人憋屈,而且布尔变量isFound纯粹是到此一游。有没有一种写法允许让代码直接从内层循环跳出外层循环呢?与其让布尔变量做标记,不如给外层循环加个记号,然后内层循环就能告诉编译器,接下来的break语句要跳出指定标记的循环。这时冒号便派上用场了,通过形如“标记名称 : for或者while”的表达式,即可给指定循环起个外号,于是语句“break 标记名称”便实现了跳出指定循环的需求。那么使用新写法改造前面的循环跳出代码,修改之后的代码如下所示:

		// 下面的loop1是一个记号,连同后面的冒号加在for前面,表示它指代这个for循环
loop1 : for (int i=0; i<triangle.length; i++) {
for (int j=0; j<triangle[i].length; j++) {
if (triangle[i][j] == 0.0) {
System.out.println("loop1 found 0.0");
break loop1; // 跳出loop1代表的循环,也就是跳出第一层循环
}
}
}

如上代码先在外层的for循环之前添加“loop1 : ”,表明外层循环的绰号叫loop1,然后内层循环的break语句改成“break loop1;”,表示跳出loop1这个外层循环,这样只需一个break语句就跳出多重循环了。除了break语句,continue也允许带上标记名称,比如“continue loop1”表示继续loop1这个外层循环的下一次循环处理,并且while循环也同样认可在break和continue后面添加标记。当然,利用前面介绍的冒号第三种用法,上面的多重循环还能简化成下述这般代码:

		// 下面用到了两种冒号,一种用来标记循环,另一种用来简化数组遍历
loop2 : for (double[] dot : triangle) { // dot等价于前面的triangle[i]
for (double coordinate : dot) { // coordinate等价于前面的triangle[i][j]
if (coordinate == 0.0) {
System.out.println("loop2 found 0.0");
break loop2; // 跳出loop2代表的循环
}
}
}

如此一来,上述的循环代码联合应用了冒号的两种用法,整个代码也变得更加精炼了。

Java开发笔记(二十二)神奇的冒号的更多相关文章

  1. Java开发笔记(十二)布尔变量论道与或非

    在编程语言的设计之初,它们除了可以进行数学计算,还常常用于逻辑推理和条件判断.为了实现逻辑判断的功能,Java引入了一种布尔类型boolean,用来表示“真”和“假”.该类型的变量只允许两个取值,即t ...

  2. Java开发笔记(一百二十五)AWT图像加工

    前面介绍了如何使用画笔工具Graphics绘制各种图案,然而Graphics并不完美,它的遗憾之处包括但不限于:1.不能设置背景颜色:2.虽然提供了平移功能,却未提供旋转功能与缩放功能:3.只能在控件 ...

  3. Java开发笔记(一百二十)AWT文本标签

    前面介绍了AWT窗口及其面板的简单用法,其中展示出来的控件只有按钮一种,还有很多好用好玩的控件有待介绍.首先是文本标签Label,该控件用于显示一段平铺文本,它不花哨也不跳动,完全就是素面朝天的文本字 ...

  4. Java开发笔记(一百二十二)AWT选择框

    前面介绍了两种文本输入框的用法,不过实际应用很少需要用户亲自文字,而是在界面上列出几个选项,让用户勾勾点点完成选择,这样既方便也不容易弄错.依据选择的唯一性,可将选项控件分为两类:一类是在方框中打勾的 ...

  5. Java开发笔记(一百二十四)AWT绘图操作

    前面介绍了如何使用画笔在控件上展示图像,可是图像来源于磁盘图片,无法即兴绘制个性化的图案.所幸画笔工具Graphics不仅能够描绘图像,还支持绘制常见的几何形状,也支持绘制文本字符串,除了绘制图像用到 ...

  6. Java开发笔记(一百二十六)Swing的窗口

    前面介绍了AWT界面编程的若干技术,在编码实践的时候,会发现AWT用起来甚是别扭,它的毛病包括但不限于下列几点:1.对中文的支持不好,要想在界面上正常显示汉字,还得在运行时指定额外的运行参数“-Dfi ...

  7. Java开发笔记(一百二十八)Swing的图标

    前面提过,AWT没提供能够直接显示图像的控件,这无疑是个令人诟病的短板,因为一上来就得由程序员自己去定义新控件,对于初学者来讲很不友好.这个问题在Swing中也解决掉了,不过Swing并未提供单独的图 ...

  8. Java开发笔记(一百二十九)Swing的输入框

    Swing的输入框仍然分成两类:单行输入框和多行输入框,但与AWT的同类控件相比,它们在若干细节上有所调整.首先说单行输入框,AWT的单行输入框名叫TextField,平时输入什么字符它便显示什么字符 ...

  9. Java开发笔记(九十二)文件通道的基本用法

    前面介绍的各色流式IO在功能方面着实强大,处理文件的时候该具备的操作应有尽有,可流式IO在性能方面不尽如人意,它的设计原理使得实际运行效率偏低,为此从Java4开始增加了NIO技术,通过全新的架构体系 ...

  10. Java开发笔记(一百二十一)AWT输入框

    前面介绍了文本标签Label,该控件展示的文字是不可编辑的,若要用户在界面上输入文本,就得使用专门的编辑框控件.在AWT的控件家族当中,用作编辑框的有两种控件,分别是单行输入框TextField和多行 ...

随机推荐

  1. android&colon; 内容提供器简介

    我们学了 Android 数据持久化的技术,包括文件存储.SharedPreferences 存 储.以及数据库存储.不知道你有没有发现,使用这些持久化技术所保存的数据都只能在当 前应用程序中访问.虽 ...

  2. asp&period;net 认证与授权

    1.下面的例子在web.config文件中配置网站使用asp.net forms 身份认证方式: <configuration> <system.web> <authen ...

  3. HDU Destroy Transportation system&lpar;有上下界的可行流&rpar;

    前几天正看着网络流,也正研究着一个有上下界的网络流的问题,查看了很多博客,觉得下面这篇概括的还是相当精确的: http://blog.csdn.net/leolin_/article/details/ ...

  4. POJ 1740

    #include <iostream> #define MAXN 100 using namespace std; int _m[MAXN]; bool mark[MAXN]; int m ...

  5. Objective-C学习篇03—继承

    大纲: 继承的基本概念 自定义初始化方法 便利构造器方法 重写description方法 一 继承基本概念 程序里的对象和"人类"的对象是一样的,高富帅继承了父母,自然就拥有了父母 ...

  6. Learning Docker--chapter 1

    CONTENTS: (1) An introduction to Docker (2) Docker on Linux (3) Differentiating between containeriza ...

  7. Unity3D&lowbar;GUI &lpar;1&rpar;--按钮控件

    这是自己的第一篇记录自己的技术文章,自己还是个菜鸟,有错误之处还望大家能够多多指点. 下面记录的是自己在学GUI.Button的自己认知,这里用的是代码进行控制,当然当你学熟练了就可以直接使用GUI ...

  8. 【转】globk和glorg中使用的apr文件

    gamit和globk分析设置先验坐标和速度的要求和规则是不同的,因为在不同的阶段和环境下需要不同.从相位数据和松弛约束坐标和它们的方差得到的精 密坐标的可靠估计是假设对先验值的调整很小,也就是说在调 ...

  9. Java GC机制中Minor GC&sol;Full GC

    Minor GC Young GC Full GC Major GC https://blog.csdn.net/chenleixing/article/details/46706039 内存划分为 ...

  10. ASP&period;NET Newtonsoft 序列化反序列化

    1.NuGet 安装 Newtonsoft 2.调用方法 一 NuGet 安装 Newtonsoft 二 调用方法 Student stu = new Student(); stu.ID = &quo ...