java学习(5)

from: http://android.yaohuiji.com/archives/2991

 

Java基础第五讲:流程控制(一)

20 SEP

java_lesson5

本讲内容: 分支语句

流程控制 Flow Control :

流程控制语句是编程语言中的核心之一。可以分为 分支语句、循环语句和跳转语句。

本讲内容包括分支语句的 if-else 和 switch , 它们又被称为判决语句(decision statements),意思是根据某种条件做出朝哪个方向前进的判断。

一、if-else分支控制语句 ( if-else Branching )

1、最简单的if语句

假设我到办公室里问黄文强在不在?如果他在的话会说在,不在的话一般情况是没人说话了。我们用程序模拟一下:

image

public class Lesson06_1 {
	public static void main(String[] args) {
		//设置黄文强在
		boolean flag = true;
		System.out.println("开始");
		if (flag){
			System.out.println("在");
		}
		System.out.println("结束");
	}
}


为了把分支语句的前后界定清楚,我加了开始和结束标识。上面的运行结果是:

image

2、最简单的if-else语句

假设我到办公室里问黄文强在不在?如果他在的话会说在,不在的时候有热心同事回答了一句“他不在”,那我就不立刻明白了。我们用程序模拟一下:

image

public class Lesson06_1 {
	public static void main(String[] args) {
		//设置黄文强不在
		boolean flag = false;
		System.out.println("开始");
		if (flag){
			System.out.println("在");
		}else{
			System.out.println("他不在");
		}
		System.out.println("结束");
	}
}


上面的运行结果是:

image

3、简单的 if – else if 语句

好吧,如果黄文强不在的话,我想问问刘克强在不在?恰好,刘克强在,那么用程序模拟是这样的:

image

public class Lesson06_1 {
	public static void main(String[] args) {
		// 设置黄文强不在
		boolean flag1 = false;
		// 设置刘克强在
		boolean flag2 = true;
		System.out.println("开始->");
		if (flag1) {
			System.out.println("黄文强在");
		} else if (flag2) {
			System.out.println("刘克强在");
		}
		System.out.println("->结束");
	}
}


上面的运行结果是:

image

4、复合 if- else if – else 语句

如果刘克强也不在,那么用程序模拟是这样的:

public class Lesson06_1 {
	public static void main(String[] args) {
		// 设置黄文强不在
		boolean flag1 = false;
		// 设置刘克强在
		boolean flag2 = true;
		System.out.println("开始->");
		if (flag1) {
			System.out.println("黄文强在");
		} else if (flag2) {
			System.out.println("刘克强在");
		} else {
			System.out.println("他们不在");
		}
		System.out.println("->结束");
	}
}


上面的运行结果是:

image

5、if-else语句规则

  1. if后的括号不能省略,括号里表达式的值最终必须返回的是布尔值
  2. 如果条件体内只有一条语句需要执行,那么if后面的大括号可以省略,但这是一种极为不好的编程习惯。
  3. 对于给定的if,else语句是可选的,else if 语句也是可选的
  4. else和else if同时出现时,else必须出现在else if 之后
  5. 如果有多条else if语句同时出现,那么如果有一条else if语句的表达式测试成功,那么会忽略掉其他所有else if和else分支。
  6. 如果出现多个if,只有一个else的情形,else子句归属于最内层的if语句

6、实例练习:

下面我们看一个例子,(请注意这个例子的写法是不被推荐的,这里这么写是为了讲解if-else的规则)

public class Lesson06 {
	public static void main(String[] args) {
		boolean examIsDone = true;
		int score = 65;
		if (examIsDone)
		if (score >= 90)System.out.println("A ,Excellent");
		else if (score >= 80)
		System.out.println("B ,Good");
		else if (score >= 70)
		System.out.println("C ,Middle");
		else if (score >= 60)
		System.out.println("D ,Pass");
		else
		System.out.println("E ,Fail");
		System.out.println("Done is Done");
	}
}


你认为else是属于哪个if语句的?System.out.println(“Done is Done”);是在哪一行代码之后执行的?

二、分支控制语句 switch Statement

Java中有一个和if语句比较相似的分支控制语句叫switch ,它在有一系列固定值做分支时使用效率要比if-else方式效率高(别急,等一下再告诉你为什么效率高)。

先看一个例子:假设我们不考虑闰年的话,我们如何知道一个月有多少天?先用if-else的方式来实现:

public class Lesson06_2 {
	public static void main(String[] args) {
		int month=9;
		if(month==1){
			System.out.println(month+"月有31天");
		}else if(month==2){
			System.out.println(month+"月有28天");
		}else if(month==3){
			System.out.println(month+"月有31天");
		}else if(month==4){
			System.out.println(month+"月有30天");
		}else if(month==5){
			System.out.println(month+"月有31天");
		}else if(month==6){
			System.out.println(month+"月有30天");
		}else if(month==7){
			System.out.println(month+"月有31天");
		}else if(month==8){
			System.out.println(month+"月有31天");
		}else if(month==9){
			System.out.println(month+"月有30天");
		}else if(month==10){
			System.out.println(month+"月有31天");
		}else if(month==11){
			System.out.println(month+"月有30天");
		}else if(month==12){
			System.out.println(month+"月有31天");
		}else{
			System.out.println("没有这个月份吧");
		}
	}
}


接下来我们使用switch语句重新实现一次:

public class Lesson06_4 {
	public static void main(String[] args) {
		int month = 9;
		switch (month) {
		case 1:
			System.out.println(month + "月有31天");
			break;
		case 2:
			System.out.println(month + "月有28天");
			break;
		case 3:
			System.out.println(month + "月有31天");
			break;
		case 4:
			System.out.println(month + "月有30天");
			break;
		case 5:
			System.out.println(month + "月有31天");
			break;
		case 6:
			System.out.println(month + "月有30天");
			break;
		case 7:
			System.out.println(month + "月有31天");
			break;
		case 8:
			System.out.println(month + "月有31天");
			break;
		case 9:
			System.out.println(month + "月有30天");
			break;
		case 10:
			System.out.println(month + "月有31天");
			break;
		case 11:
			System.out.println(month + "月有30天");
			break;
		case 12:
			System.out.println(month + "月有31天");
			break;
		default:
			System.out.println("没有这个月份吧");
			break;
		}
	}
}


运行2个程序,结果都是 9月有30天。

image

从简洁程度和效率上,switch都略胜一筹(上面的2个程序,把输出语句屏蔽掉,各自循环运行10亿次,switch快了6636毫秒,也就是6秒钟)。

为什么会快一些呢,因为switch是在编译时优化的。运行时进行的不是变量的比较运算,而是直接跳转。举个例子7×9你是反射式的出来的结果,9×7你需要稍稍楞一小下,99×7你就需要计算一下了。这就是他们之间的区别。如果你觉得举例子不科学,改天我们再找虚拟机一起聊这个话题^_^

好了,我们还是先学习一下switch都有什么使用规则吧:

1、留意switch格式的写法

标准且合法的格式:

image

非法格式说明:

switch(x){

case 0 {}

}

switch(x){

0:{}

1:{}

}

能看到哪里错了吧,第一个没冒号,第二个没case关键字

2、switch表达式必须能被求值成char byte short int 或 enum

记忆的话可以记忆成非lang整形加枚举。请切记在java 6 及以前版本中string是不允许用在switch表达式中的(Java 7可以用string,现在正式版还没出来)

3、case常量必须是编译时常量,因为case的参数必须在编译时解析,也就是说必须是字面量或者是在声明时就赋值的final变量。

这个不太好理解,举个例子看看:

public class Lesson06_5 {
	public static void main(String[] args) {
		final int a = 2;
		final int b;
		b = 3;
		int x =2;
		switch(x){
			case 1: //编译OK
			case a: //编译OK
			case b: //无法通过编译
		}
	}
}


编译一下看看:

image

4、case常量被会转换成switch表达式的类型,如果类型不匹配也会出错:

public class Lesson06_5 {
	public static void main(String[] args) {
		byte x =2;
		switch(x){
			case 1: //编译OK
			case 128: //无法自动转换成byte,编译器会报错		}
	}
}


image

5、多个case常量重复也会出错:

public class Lesson06_5 {
	public static void main(String[] args) {
		byte x =2;
		switch(x){
			case 1: //编译OK
			case 1:
		}
	}
}


编译一下看看:

image

6、匹配的case的语句是入口而不是独立分支:

public class Lesson06_5 {
	public static void main(String[] args) {
		int x = 1;
		switch (x) {
			case 1:System.out.println("周一");
			case 2:System.out.println("周二");
			case 3:System.out.println("周三");
			case 4:System.out.println("周四");
			case 5:System.out.println("周五");
			case 6:System.out.println("周六");
			case 7:System.out.println("周日");
			default:System.out.println("这个是星期几啊");
		}
	}
}


image

switch代码是找到一个匹配的case常量入口,然后自顶向下执行的。也就是英文里的Fall-Through,你可以形象的理解他的执行方式是自由落体式的一股脑碰到啥就执行啥。

7、break:在switch语句块中,执行到break关键词时,立刻退出switch语句块,转到switch的下一条语句。

我们结合6、7两点规则来重写一次,判断月份天数的例子:

public class Lesson06_3 {
	public static void main(String[] args) {
		int month = 9;
		switch (month) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			System.out.println(month + "月有31天");
			break;
		case 2:
			System.out.println(month + "月有28天");
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			System.out.println(month + "月有30天");
			break;
		default:
			System.out.println("没有这个月份吧");
			break;
		}
	}
}


运行程序:

image

8、default :当switch中所有的case常量都不匹配时,会执行default分支:

再把上面判断星期几的代码改一下:

public class Lesson06_5 {
	public static void main(String[] args) {
		int x = 8;
		switch (x) {
			case 1:System.out.println("周一");
			default:System.out.println("这个是星期几啊");
			case 2:System.out.println("周二");
			case 3:System.out.println("周三");
			case 4:System.out.println("周四");
			case 5:System.out.println("周五");
			break;
			case 6:System.out.println("周六");
			case 7:System.out.println("周日");
		}
	}
}


运行程序:

image

我们故意写了星期8,所以触发了default分支,可是因为没有使用break语句,所以又直落执行了。于是出现了这个看起来有点奇怪,其实很正常的输出。

好了,到这里我们就把switch讲完了。大家要记住的是当程序中有很多需要判断的成点状数据需要分别处理时优先采用switch,如果遇到区间判断时,不用思考,还是用if-else吧。

对编程基础知识的理解会随着你的编程经验不断加深,不要奢望一次理解有多到位,淡定,淡定。

本讲就到这里,Take your time and enjoy it .

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值