流程控制、迭代器
分支结构
一、if 条件语句
if语句有四种形式
第一种形式:
if( logic expression ){
statement….
}
单个if的判断是比较常用的。就不举例说明了。
第二种形式:
if( logicexpression ){
statement...
}
else{
statement…
}
这种形式的if判断语句主要使用于非0即1,非1即0的情况。好像boolean类型,只有两种情况。就比如学生成绩一样,大于等于六十分就是及格否则不及格。
第三种形式:
if( logicexpression ){
statement…..
}
else if ( logicexpression ){
statement….
}
…// 可有零或者多个 else if 语句
else{
statement…
}
对于第三和第四这两种情况,我举例说明一下。
有这么一个需求,输入一个学生成绩,在0到100之间,
如果分数在0到59 输出E,分数在60到69 输出D,分数在70到79 输出C,
分数在80到89 输出B,大于等于90输出A;
我们有可能会写成如code1.java所示代码:
程序清单: code1.java
public class code1{
public static void main(String[] arg)
{
Scanner cin = new Scanner(System.in);
while(cin.hasNext())
{
int n = cin.nextInt();
if(n<60) System.out.println("E");
if(n<70) System.out.println("D");
if(n<80) System.out.println("C");
if(n<90) System.out.println("B");
else System.out.println("A");
}
}
表面上看起来没有任何问题,但是运行起来会出现各种问题。加入输入20,则会把E,D,C,B,A全部打印出来。我们会很疑惑怎么会出现这种情况呢?主要是因为if判断,标识每个if都会被判断一次,还有那个else 至于判不判断,是看和else最近的if中的代码有没有执行。
注意:上面的代码中if之后没有出现花括号,if语句默认其下面一句也就是第一个分号前的语句为其要执行的语句。
if(n<60) System.out.println("E");
System.out.println("BBB");
else System.out.println("A");
不要出现这样的格式错误,else 会报错,else 默认和上面第一个if语句匹配,但是if语句是一个独立的,相当于if(n<60){
System.out.println("E");
}
造成else 无法与if匹配,导致错误发生,建议每个if( logic expression)后跟上花括号。
如何修改采用一种方法在if语句中添加逻辑运算。改成如下代码就对了。
if(n<60) System.out.println("E");
if(n>=60&&n<70) System.out.println("D");
if(n>=70&&n<80) System.out.println("C");
if(n>=80&&n<90) System.out.println("B");
if(n>=90) System.out.println("A");
采用第三种形式一般我们直接会写code2.java所示的代码:
程序清单: code2.java
public class code2{
public static void main(String[] arg)
{
Scanner cin = new Scanner(System.in);
while(cin.hasNext())
{
int n = cin.nextInt();
if(n<59) System.out.println("E");
else if(n<70) System.out.println("D");
else if(n>=70&&n<80) System.out.println("C");
else if(n>=80&&n<90) System.out.println("B");
else System.out.println("A");
}
}
}
这样方法就不会出现code1.java出现的情况。
采用这种结构,每次只能执行其中一个 if 、else if 、 else 语句,有点像在执行代码垮中添加了一个continue语句。
二、switch 分支语句
switch语句由一个控制表达式和多个case标签组成,和if语句不同的是,switch语句后面的控制表达式数据类型只能是byte、short、char、int四个基本数据类型和枚举类。Java 7新增了String类型。
格式如下:
switch(expression ){
casecondition1:
{
statement(s)
Break;
}
casecondition1:
{
statement(s)
Break;
}
casecondition1:
{
statement(s)
Break;
}
default:
{
statement(s)
}
}
Switch是依次匹配conditionX(X 0,1,...,n),遇到匹配的立即执行对应的代码。如果所有的都不匹配则执行default标签后的代码块。
Switch可以省略花括号,但是不能省略break,省略break会出现各种奇妙的现象。
说一下switch语句的运行流程:switch语句会先求出expression的值,然后和case标签后的值进行比较,如果相等,程序就开始执行case标签后的,不再判断case和default标签的条件是否匹配,直到遇见break才会结束。
Switch java 7 行特性,新增String类型举例,如代码code3.java :
程序清单: code3.java
public class code3{
public static void main(String[] args)throws IOException
{
String season = "spring";
switch(season)
{
case "spring": System.out.println("春天来了");break;
case "summer": System.out.println("夏天来了");break;
case "fall": System.out.println("球天来了");break;
case "winter": System.out.println("冬天来了");break;
}
}
}
//上面代码的运行环境为java 1.7
有个不经意的小知识点switch的效率比if的执行效率要高。
switch优点
当分支较多时,用switch的效率是很高的。因为switch是随机访问的,就是确定了选择值之后直接跳转到那个特定的分支,但是if else是遍历所以得可能值,知道找到符合条件的分支。如此看来,switch的效率确实比if else要高的多。
但是case常量分布范围很大但实际有效值又比较少的情况,switch的空间利用率将变得很低。
if优点
switch只能处理常量的情况,对非常量的情况是无能为力的。像a > 1 && a < 100,这种表达式是无法使用switch的,只能用if else。所以if else能应用于更多的场合。
循环结构:
顾名思义就是重复的去执行一段代码,这段被重复执行的代码成为循环体。想要结束循环只要把循环条件改为假即可,循环结束,否则一直执行下去,造成死循环。循环语句包括下面几个部分:
初始化语句:在循环开始前执行的语句,用于完成一些初始化工作。
循环条件:一个boolean表达式,用来判断是否执行循环体。
循环体:循环的主体,如果循环条件允许,代码将被重复执行。
迭代语句:在循环体结束后执行的语句,用来控制循环条件中的变量,控制循环是否结束。
三大循环语句:while,do while, for
一、while循环
while循环语法格式:
init_statement
while(expression)
{
statement;
iterator_statment;
}
While循环每次执行之前先对expression求值,如果逻辑表达式为true,则运行循环体部分。如果expression第一次判断为false,那么循环体永远不能执行。
如果while循环后的循环体和迭代语句合并在一起,只有一句,可以省略花括号,可能会降低程序的可读性。
注意:使用while循环的时候一定要保证循环条件为false的时候,不然会造成一个死循环。
二、do while 循环
do while 循环语法格式:
init_statement
do
{
statement;
iterator_statment;
} while( expression);
do while 和while的区别在于,while是先判断后执行,do while恰好相反,也就是说do while语句中循环体至少执行一次。如果do while 中的循环体和迭代部分合并成了一行代码可以省略或括号,可能会降低程序可读性;
注意:do while 循环的循环条件后面必须有一个分号,来声明循环结束;
三、for循环
for循环是比较见解的循环语句,大部分情况下可以代替while,do while 循环。for循环的基本语法格式:
for( init_statement ; expressiong; iteratro_statement){
statement;
}
执行for循环的流程,先执行循环条件的初始化语句init_statement,初始化语句只执行一次。每次执行循环体之前先计算expression循环条件的值,如果为true则执行循环体部分,结束后执行循环迭代语句。如果循环体只有一句可以省略花括号。
for循环圆括号中的唯一不能省略就是两个分号,如代码code4.java所示:
程序清单: code4.java
publicclass code4{
public static void main(String[] args)throws IOException
{
// 省略了三个部分,循环条件将一直为true(这种结构默认循环条件为true)
for(;;)
{
System.out.println("死循环");
}
}
}
注意:for循环和while,do while循环不一样:由于while,do while循环的循环迭代语句紧跟循环体,因此如果循环体不能完全执行,如使用continue语句来结束本次循环,则迭代语句不会执行。但for循环的循环迭代语句并没有与循环体放在一起,因此不管是否使用continue语句来结束本次循环,循环迭代语句一样会获得执行。
*四、循环嵌套
如果把一个循环结构放在另一个循环体内,就可以形成循环嵌套,可以随便组合使用各种循环语句。最熟悉的例子莫过于数组排序。
控制循环结构
用来控制循环结构,提高程序可读性。Java提供continue和break来控制循环结构,还可以使用return来结束整个方法。
一、break结束循环
break用来结束当前循环,并跳出循环体。break不仅可以结束其所在的循环,还可以使用标签,结束其外层循环。Java中的标签就是紧跟着英文冒号:的标识符。Java中的标签只有放在循环语句前才有效。如code5.java所示:
程序清单: code5.java
publicclass code5{
public static void main(String[] args)throws IOException
{
// 外层循环 Outer作为标识符
Outer:
for(int i=0;i<10;i++){
for(int j=0;j<5;j++){
System.out.println("i的值是:"+i+"\tj的值是:"+j);
if(j==3){
break Outer;
}
}
}
}
}
打印结果:
i的值是:0 j的值是:0
i的值是:0 j的值是:1
i的值是:0 j的值是:2
i的值是:0 j的值是:3
程序从外层循环进入内层循环后,当j等于3时,程序遇到break Outer; 语句,这段代码会直接结束Outer标签指定的循环,而不是break所在的循环。
二、continue结束本次循环
continue只是跳出本次的循环,接着开始下一次循环;而break是完全结束循环本身。如代码code6.java所示:
程序清单: code6.java
public class code6{
public static void main(String[] args)throws IOException
{
for(int i=0;i<5;i++){
if(i%2==0)continue;
System.out.println("输出结果:"+i);
}
}
}
打印结果:
输出结果:1
输出结果:3
从运行结果来看,当i为偶数时,程序忽略了continue; 语句之后的代码。
和break类似,continue也可以跟一个标签,用于直接跳过所标识循环的当前循环剩下的语句,重新开始下一次循环。如代码code7.java所示:
程序清单: code7.java
publicclass code7{
public static void main(String[] args)throws IOException
{
// 外层循环
Outer:
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
System.out.println("i的值是:"+i+"\tj的值是:"+j);
if(j==1){
continue Outer;
}
}
}
}
}
从结果可以看出j的值无法超过1,每当j等于1时,continu Outer;语句就会跳出外层循环的当次循环,开始下一次外层循环,内层循环没有机会执行。
三、return结束方法
return 关键字一般用于结束一个方法。当一个方法执行到return语句,这个方法将被结束。在循环体内执行到一个return语句,return语句机会结束该方法,循环也随之结束。