系列连载文章,大家可以从我的专栏学习Java入门基础知识,后续也会有更高级的Java特性、企业级开发框架,也有平常工作中的技术总结和分享,欢迎关注我的CDSN博客。同时可关注微信公众号“Java开发之旅”,获得更多技术资料!
目录
闲言碎语
浅谈Java中的程序结构
关系运算符、布尔变量、关系表达式、逻辑运算符
if结构的语法
&和|运算符
小结
在之前的几篇内容,我们学习了Java当中的变量定义、变量运算。从今天开始我们将正式的学习Java语法、Java当中的程序控制结构,来实现代码中的逻辑、控制,这也是进行开发的基础。
另外说一点,此系列的教程是从0开始的,如果你是有一定经验的开发者,更多的技术分享、学习资料还请大家关注我的其他专栏,我会及时将博客里的所有文章进行归档,方便大家查阅。
Java当中的程序结构,总的来说分为3种:
顺序结构
选择结构
循环结构
所有的Java程序都是这3种结构的组合,没有例外,代码的千变万化是由我们的思维逻辑组成的,但是你永远不可能跳出这3种结构。
顺序结构,就是我们之前写的那些代码,从上往下依次执行,没用选择、没有控制,只要程序不报错就可以从头执行到尾;
选择结构,是我们今天要学习的一种控制结构,有了它才能实现逻辑的控制,比如在凌晨4点做运动,要先判断你是否是罗某祥……噢不对,比如在支付订单的时候,要先判断你的余额是否充足;
循环结构,即重复地做某件事、重复地执行一段代码,在不久的讲来为大家介绍。
在编写if结构之前,我们需要先学习逻辑运算符和布尔变量。
Java当中一共有四种运算符:算术运算符、关系运算符、逻辑运算符、位运算符。算术运算符就是之前和大家介绍的加减乘除、取余,关系运算符和逻辑运算符是我们这节课要分享的内容,位运算符会放在以后介绍。
关系运算符,顾名思义是用于比较的,一共有下面几种关系运算符:
布尔变量在之前为大家介绍过,它只有两种值:true和false,表示真和假,它的声明语法是:
boolean 变量名 = 布尔值;
布尔值就是true或者false,除了直接指定布尔值,我们还可以通过关系表达式来获取。那什么是关系表达式呢?
上面表格中的用例,其实就是关系表达式,关系表达式是一种返回布尔值的表达式,由比较元素、关系运算符构成,关系运算符两边的即是用于比较的元素。如果两个元素的关系满足表达式中关系运算符的定义,就返回true,不满足就返回false。
比如,1>2,这个关系表达式的比较元素是1和2,定义的关系运算符是大于,显然1并不大于2,所以这个关系表达式的结果是false。
我们上面说到,关系表达式最终返回布尔值,所以以下代码是正确的:
boolean flag = 1 > 2; //等价于boolean flag = false;
上面的关系运算符、布尔值、关系表达式,可以实现基本的逻辑控制,但有时候我们需要更多的条件判断。比如某个用户需要是VIP、而且买了超前点播才能观看某个电视剧,那这里显然就是多个条件的组合。
在Java当中,提供了以下几种逻辑运算符,用于多个关系表达式的组合:
&&表示并且关系、与的关系,只有当它两边的表达式都是true,才会返回true,有一个是false就返回false,比如:
boolean flag = (1 == 1) && (2 >= 0); //返回true,等价于boolean flag = true;
boolean ans = (1 == 1) && (2 > 3); //返回false,等价于boolean ans = false;
||表示或者关系,它两边的表达式只要有一个是true,就返回true,哪怕另一个是false;只有两边的表达式都返回false,才会最终返回false,比如:
boolean flag = (1 > 0) || (2 > 3); //返回true,等价于boolean flag = true;
boolean ans = (1 > 2) || (2 > 3); //返回false,等价于boolean ans = false;
!表示非、否、不是,是一种取反,你修饰的是true,那么加上!就是false,修饰的是false那么加上!之后就变成了true,有点颠倒黑白的意思,以下代码注意看注释:
boolean flag = !true; //返回false,等价于boolean flag = false;
boolean ans = !false; //返回true,等价于boolean ans = true;
boolean ans = !(1>2); //返回true,因为1>2返回的是false,取反之后就是true
boolean ans = !((1>0) && (3 > 1)); //返回false,因为(1>0) && (3>1)返回了true,再对整个表达式进行取反,就是false
^表示相异,当两个表达式或布尔值不相同,就返回true,相同就返回false:
//返回true,因为true和false是两个不同的值
boolean ans = true ^ false;
//返回false,因为^两边都是相同的值
boolean ans = true ^ true;
//返回false,因为^两边都是相同的值
boolean ans = false ^ false;
那&和|呢?这两个其实也属于位运算符,涉及到二进制的东西,介绍它们和&&、||的区别篇幅会比较长,我在本文的最后和大家讲解,大家也可以下滑到底部进行查看。
if结构有以下3种写法:
if (布尔值) {
//要执行的代码块
}
if (布尔值) {
//要执行的代码块
} else {
//要执行的代码块
}
if (布尔值) {
//要执行的代码块
} else if (布尔值) {
//要执行的代码块,可以有多个else if模块
} else {
//要执行的代码块,此处的else也可以省略不要
}
第1种if结构是最简单的结构,当if关键字后面的小括号里的布尔值为true,就会执行大括号里所包含的代码,为false就不执行:
public class Test {
public static void main(String[] args) {
System.out.println("程序开始执行");
boolean ans = true;
if (ans) {
System.out.println("满足条件,进入了if模块");
}
System.out.println("程序执行完毕");
}
}
以上代码的执行结果:
程序开始执行
满足条件,进入了if模块
程序执行完毕
如果将布尔变量ans的值变成false,输出结果就是:
程序开始执行
程序执行完毕
另外,由于if结构的小括号里面需要的是布尔值,而布尔值有以下几种方式获得:
直接写定布尔值
boolean类型的变量
关系表达式
逻辑表达式
我们上面的代码是通过boolean类型的变量获取布尔值,以下方式也是可行的:
if (true) {
//可以进来,换成false就不行,不再演示
}
if (1 > 2) {
//进不来,因为1 > 2返回的是false
}
if ((1 > 0) && (2 > 1)) {
//可以进来,因为 (1 > 0) && (2 > 1) 返回的是true
}
下面来说说第二种if结构,第二种if结构是第一种if的升级改造,它提供了一个else结构,当if后面的布尔值是true就执行if里的代码,是false就执行else里的代码:
public class Test {
public static void main(String[] args) {
System.out.println("用户尝试观看《庆余年》");
boolean vip = true;
if (vip) {
System.out.println("恭喜您,尊敬的VIP,我是小舔狗,您可以观看此视频");
}else {
System.out.println("您不是VIP用户,无法观看此视频");
}
}
}
当vip变量为true:
用户尝试观看《庆余年》
恭喜您,尊敬的VIP,我是小舔狗,您可以观看此视频
当vip变量为false:
用户尝试观看《庆余年》
您不是VIP用户,无法观看此视频
第3种if结构,是一种多层次的选择。当if后面的布尔值是true,就直接执行if里面的代码块,整个结构结束;当if后面的布尔值是false,就判断下一个else if里面的布尔值,是true就执行这个else if里面的代码块,整个结构结束,否则继续往下判断,找到满足的else if为止;如果if和所有的else if都不满足,就执行最后的else代码块。
有点绕是吧?来看一个例子:
public class Test {
public static void main(String[] args) {
//分数
int score = 80;
if (score >= 95) {
//如果大于等于95分,优秀级别
System.out.println("优秀");
}else if (score >= 80) {
//如果大于等于80分,良好
System.out.println("良好");
}else if (score >= 70) {
System.out.println("快挨揍了");
}else {
System.out.println("70分都考不到,去吃翔吧……");
}
System.out.println("执行完毕");
}
}
运行结果是:
良好
执行完毕
下面解析一下这个程序的执行流程:
因为这里给的值是80,首先判断if里面的表达式,80 >= 95是false,不满足,往下判断else if;第一个else if里面是80 >= 80,满足,进入到代码块,输出“良好”,整个if-else if-else结构结束,虽然下一个else if里的80 >= 70也满足,但是不会继续执行了,直接跳出这个结构,执行第17行,输出“执行完毕”。
如果你把score的值变为60,那么if和所有的else if都不满足,那将会执行else里的代码块:
70分都考不到,去吃翔吧……
执行完毕
以上就是3种if结构的用法,它的语法很简单,真正需要的其实是你的逻辑思维,再复杂的业务也逃不过这3种语法,但是就看你清不清楚怎么用、用哪个、怎么判断,归根到底还是逻辑思维的发散。
在最后,向大家介绍一下&和|运算符,这两个准确的来说是位运算符,只是可以用于逻辑判断而已,所以也叫按位与、按位或。
&,是将两个二进制数字的每一位进行逐个比较,如果两个数的当前位全是1,那么就返回1,有一个是0就返回0,两个全是0也返回0。简而言之,只有两个数的当前位全是1,才会返回1,其余情况都返回0。
具体是怎样运算呢?这就需要先给大家介绍一下二进制的转换,比如我们将十进制的3转换为二进制,步骤如下:
我们将3每次都除2,将商写在下面,余数写在右面,一直除到商为0,此时将右面的余数从下往上写,就是3的二进制了,即11。
十进制的5转为二进制:
所以十进制的5转为二进制是101,那现在我们进行一个运算:3&5,结合上面介绍的位运算,流程如下(101是三位,11是两位,所以11的前面要补0,即011):
位运算的结果就是二进制的001,把001转成十进制就是1,即001就是十进制中的1,所以3&5的最终结果是1:
|运算符同样也是进行位运算,只不过它的逻辑是:同一位上的两个数字全是0就返回0,其余的情况都返回1。
我们上面计算出了3的二进制是011,5的二进制是101,所以3|5的位运算结果是二进制的111,将二进制的111转为十进制就是7,所以最终结果是7:
说到这里,&和|的位运算就介绍完了,那它们为什么可以进行逻辑判断呢?其实,计算机中的boolean类型变量,0表示false、1表示true,只不过Java当中不支持这样的数据类型转换。
true&false其实就是1&0,位运算的结果就是0,0就是false。true|false,其实就是1|0,位运算的结果是1,1就是true,所以它们两个在功能上等价于&&、||,可以当作逻辑运算符来用,只不过平常不怎么使用这两个而已。
还有最重要的一个特点,就是&&、||具有短路功能。什么意思呢?因为&&要求两边都是true才会返回true,如果&&前边已经得到了false,那么其实后边已经没必要进行判断了,结论已经出来了那就是返回false;同理,||运算符如果在前边已经得到了true,后边的关系表达式或布尔值也不会再进行判断:
//这里不会判断后面的2>1,因为前面的1>2已经决定表达式的值是false了
if ((1 > 2) && (2 > 1))
//同理这里也不会判断后面的0==0,前面的1>0已经决定了表达式的值为true
if ((1 > 0) || (0 == 0))
但是&和|就没有这样的短路功能,它俩比较笨,哪怕是已经得到了结论,也要把后边的表达式执行一遍,通过上面介绍的位运算我们也可以理解这一点,毕竟它要将两边的结果转换为二进制,所以都要执行一遍。
看个例子:
public class Test {
public static void main(String[] args) {
int num = 1;
if ((1 > 0) | (++num > 1)) {
System.out.println("进来了");
}else {
System.out.println("没进来");
}
System.out.println("num的值:" + num);
}
}
解析一下上面的代码,按理来说|前面的1 > 0已经得到了true,在或者的关系下应该直接得到true,不再执行 ++num > 1 的比较,从而执行第6行的代码。但正是因为|运算符没有短路功能,所以还是执行了 ++num > 1这个表达式,而++运算符我们之前介绍过,写在变量的前面会“先计算、再使用”,所以这里的第二个表达式其实是 2 > 1,也是返回true的。
最后输出的num值是2,证明了我们的上述解析:
&的原理和|一样,没有短路功能,大家可以自己下去试试,我就不举例了。
今天带大家学习了关系运算符、逻辑运算符、关系表达式(也叫布尔表达式)、3种if选择结构以及&、|两个位运算符。
大家可以去网上搜一下关于if结构的练习题,从这一节开始实际上你的代码已经开始有逻辑了,要及时训练自己的思维。做不出来不要紧,看着参考答案去理解、思考,想想代码是怎样一行一行的执行下去的。
有任何问题欢迎给我的公众号发私信,或者加我个人微信寻求技术支持: