条件语句
在Java中,条件语句的格式为
if(condition)statement
这里的条件必须用括号括起来。与绝大多数程序设计语言一样,Java常常希望在某个条件为真时执行多条语句。在这样的情况下,应该使用块语句,例如:
if(a>=b){
System.out.println(a);
}
另外,我们需要介绍一下代码块。什么是代码块?
块,是指由一对大括号括起来的若干条简单的java语句。块确定了变量的作用域。一个块可以嵌套到另一个块中。需要注意的是,不能在嵌套的两个块中声明同名的变量。
在Java中,if经常和else搭配。例如:
if(a>=b){
System.out.println(a);
}else{
System.out.println(b);
}
其中else部分是可选的。else子句与最邻近的if构成一组。
重复出现if…else…是一个很正常的情况。需要注意的是,else是与哪一个if配对。
多重选择
在处理多个选项时,使用if/else结构显得有些笨重。Java中用一个与C语言完全一样的switch语句。
例如,我们建立一个包含4个选项的菜单系统。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("select an option on (1,2,3,4)");
int i = in.nextInt();
switch (i){
case 1:
System.out.println(i);
break;
case 2:
System.out.println(i);
break;
case 3:
System.out.println(i);
break;
case 4:
System.out.println(i);
break;
default:
System.out.println("无");
break;
}
}
switc语句将从与选项值相匹配的case标签处开始执行直到遇到break语句,或者执行到switch语句的结束处为止。如果没有匹配的case标签,那么,执行default子句。
需要我们注意的是,我们在编程序的时候,可能会触发多个case分支。如果在case分支语句的末尾没有break语句,那就会接着执行下一个case分支语句。这种情况相当危险,常常引发错误。所以,我们在程序中尽量少用switch语句。
case的标签可以是:
- 类型为char、byte、short或int的常量表达式。
- 枚举常量(当在switch语句中使用枚举常量时,不必再每个标签中指明枚举名,可以有switch的表达式值确定)
- 从Java se 7开始,case标签还可以是字符串字面量
循环
1. while循环
当条件为真(true)时,while循环执行一条语句(也可以是一个语句块)。格式为:
while(condition)statement
如果开始条件为flase,那么一次也不执行。
我们以一个例子来说明,该程序是计算需要多长时间才能存够一定的退休金。
public class RetirementTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("how much money do you need to retire?");
double v = in.nextDouble();
System.out.println("how much money will you contribute every year?");
double v1 = in.nextDouble();
System.out.println("interest rate in %:");
double v2 = in.nextDouble();
double balance=0;
int years=0;
while (balance<v){
balance+=v1;
double interest= balance*(v2/100);
balance+=interest;
System.out.println(balance);
years++;
}
System.out.println("you can retire in"+years+" years.");
}
}
在这个例子中,我们的循环是一个计数器,在循环体中更新当前累积的数量,直到条件为false为止。
while (balance<v){
balance+=v1;
double interest= balance*(v2/100);
balance+=interest;
System.out.println(balance);
years++;
}
while循环语句首先检测循环条件。因此,循环体中的代码有可能不被执行。如果希望循环体至少执行一次,那么,应该将检测条件放到最后。使用do while循环。
2. do while循环
语法格式为:
do statement while (condition)
这种循环先执行语句(通常是一个语句块),再检测循环条件;然后重复语句,依次类推。例如:
do {
balance+=v1;
double interest= balance*(v2/100);
balance+=interest;
System.out.println(balance);
years++;
}
while (balance < v);
3. for 循环
for循环是支持迭代的一种通用结构,利用每次迭代之后更新的计数器或类似的变量来控制迭代次数。
下面的程序将0~9输出到屏幕上:
for (int i = 0; i < 10; i++) {
System.out.println(i);
}
for循环的第一部分通常用于对计数器进行初始化;第二部分给出新一轮循环执行前要检测的循环条件;第三部分指示如何更新计数器。我们需要知道的是Java允许在for循环的各个部分放置任何表达式,但有一条不成文的规则:for语句的3个部分应该对同一个变量进行初始化、检测和更新。
我们要注意的是,在循环中检测两个浮点数是否相等需要格外小心。如下面的for循环
for (double x = 0; x !=10 ; x+=0.1) {
System.out.println(x);
}
永远不会结束。由于舍入的误差,最终可能得不到精确值。例如,在上面的循环中,因为0.1无法精确用二进制表示,所以x将从9.99999999998跳到10.0999999998.
我们在for语句的第一部分中声明了一个变量之后,这个变量的作用域就为for循环的这个循环体。
特别需要指出的是,如果在for语句内部定义一个变量,这个变量就不能在循环体之外使用。因此,如果希望在for循环体之外使用循环计数器的最终值,就要确保这个变量在for循环外声明。
int x;
for (x = 0; x !=10 ; x+=0.1) {
System.out.println(x);
}
另一方面,我们可以在各自独立的不同for循环中定义同名的变量。即,不同的for循环计数器的命名可以相同。
除此之外,for循环语句只不过是while循环的一种简化形式。
我们以下面的程序作为应用for循环的一个例子。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("how many number do you need to draw?");
int i = in.nextInt();
System.out.println("what is the highest number you can draw?");
int i1 = in.nextInt();
int c=1;
for (int j = 1; j <= i; j++) {
c=c*(i1-j+1)/j;
System.out.println("your odds are 1 in "+c+" . good luck!");
}
}
这个程序是用来计算抽奖概率。
在Java中有一种功能很强的循环结构,可以用来依次处理数组中的每一个元素而不必为指定下标值而分心。这种增强的for循环的语句格式为:
for(vatiable :collection)statement
定义一个变量用于暂存集合中的每一个元素,并执行相应的语句。
例如:
for(int element:a)
sout(element);
打印数组a中的每一个元素,一个元素占一行。当然,传统的for循环也可以实现。但是,for each循环语句显得更加简洁、不易出错。
4. 中断控制流程
break分为两种,一种带标签,一种不带标签。
我们首先来看一下不带标签的break语句。与用于退出的switch语句的break语句一样,它也可以用于退出循环语句。例如:
while (years<=100){
balance+=payment;
double interest=balance*interestRate/100;
balance+=interest;
if(balance>=goal){
break;
}
years++;
}
在循环开始时,如果years>100,或者在循环体中balance>=goal,则退出循环语句。
下面,我们来看一下带标签的break语句,用于跳出多重嵌套的循环语句。这里用个示例说明了break的工作状态。需要注意的是,标签必须放在希望跳出的最外层循环之前,并且必须跟紧一个冒号。
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n;
read_data:
while (...){
...
for(...){
System.out.println("enter a number >=0:");
n = in.nextInt();
if(n>0){
break read_data;
....
}
}
}
}
如果输入有误,通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句 代码都需要检测循环是否正常结束,还是由break跳出。
事实上,可以将标签应用到任何语句中,甚至可以应用于if语句或者块语句中,如下所示:
label:{
...
if(condition)
break label;
...
}
另外,需要注意的是,只能跳出语句块,不能跳入语句块。
除break语句之外,还有一个continue语句。与break语句一样,它将中断正常的控制流程。continue语句将控制转移到最内层循环的首部。例如:
Scanner in = new Scanner(System.in);
while (sum<goal) {
System.out.println("enter a number: ");
int i = in.nextInt();
if (i < 0) {
continue;
}
sum+=n;
}
如果n<0,则continue语句越过了当前循环体的剩余部分,立即跳到循环首部。
如果将continue用于for循环,就可以跳到for循环的“更新”部分。
还有一种带标签的continue语句,将跳到与标签匹配的循环首部。这里,不做演示。