java的流程与控制
输入与输出
在java中println
是print line的缩写指的是换行输出,如果不想换行输出可以使用print()如下:
public class In {
public static void main(String[] args) {
System.out.print("a,");
System.out.print("b,");
System.out.println();
System.out.println("end");
}
}
格式化输出
java还提供了格式化输出的功能,为啥要格式话输出呢,因为计算机输出的数据不适合人去阅读。
如果要把数据显示成我们期望的格式,就需要使用格式化输出的功能。格式化输出使用System.out.printf()
,通过使用占位符%?,printf()
可以把后面的参数格式化成指定格式:
public class In {
public static void main(String[] args) {
double d=3.1415926;
System.out.printf("%.2f\n",d);//显示两位小数3.14
System.out.printf("%.4f\n",d);//显示四位小数3.1416
}
}
java的格式化功能提供了多种占位符,可以把各种数据类型“格式化”成指定的字符串:
占位符 说明
%d 格式化输出整数
%x 格式化输出十六进制整数
%f 格式化输出浮点数
%e 格式化输出科学计数法表示的浮点数
%s 格式化字符串
注意%是一个占位符,因此%%表示%字符本身。
占位符本身还可以有更详细的格式化参数。下面的例子把一个整数格式化成十六进制,并用0补足8位:
public class In {
public static void main(String[] args) {
int d=12345000;
System.out.printf("d=%d\n hex=%08x\n",d,d);// 注意,两个%占位符必须传入两个数
}
}
输入
和输出相比,java输入复杂多了。我们来看以下的例子:
import java.util.Scanner;
public class Output {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);//创建scanner对象
System.out.print("输入您的姓名:");//打印输出:输入您的姓名
String name =scanner.nextLine();//读取一行输入,并获取字符串
System.out.print("输入您的年龄:");//打印输出:输入您的年龄
int age=scanner.nextInt();//读取输入,并获取整数
System.out.printf("你好! %s,您的年龄是 %d\n",name,age);//打印输出获取的字符串和整数
}
}
首先,我们通过import语句导入java.util.Scanner,import是导入某个类的语句,必须放到Java源代码的开头,然后,创建Scanner对象并传入System.in。System.out代表标准输出流,而System.in代表标准输入流。直接使用System.in读取用户输入虽然是可以的,但需要更复杂的代码,而通过Scanner就可以简化后续的代码。
有了Scanner对象后,要读取用户输入的字符串,使用scanner.nextLine()
,要读取用户输入的整数,使用scanner.nextInt()。
if判断
在java程序中,如果需要根据条件来决定是否执行代码,可以同通过if语句来实现。
if的语句的定义:
if(条件)
{
//当符合条件,执行语句
}
根据if的计算结果(true还是false),来决定是否执行接下来的语句。
举个例子:
import java.util.Scanner;
public class If {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.print("请输入本次的考试成绩:");
int n=scanner.nextInt();
if(n>=60)
{
System.out.println("及格了!");
}
System.out.println("End");
}
}
当条件n >= 60计算结果为true时,if语句块被执行,将打印"及格了",否则,if语句块将被跳过。修改n的值可以看到执行效果。
if语句的花括号可以包含对个语句:
if(n>=60)
{
System.out.ptintln("恭喜你");
System.out.ptintln("及格了");
}
当只有一句语句需要执行时,可以省略花括号,建议一般不要省略。
else
if语句还可以编写一个else { … },当条件判断为false时,将执行else的语句块:
if(n>=60)
{
System.out.println("及格了!恭喜你!");
}
else {
System.out.println("未及格,需要补考!");
}
System.out.println("本次查询结束!");
}
修改上述代码n的值,观察if条件为true或false时,程序执行的语句块。
注意,else不是必须的。
也可以将if(条件){} else{}多个连起来使用,在使用if和else if的串联时需要注意顺序和范围大小,如下:
if(n>=90) {
System.out.println("优秀,奖励一朵小红花!");
}
else if(n>=60)
{
System.out.println("及格了!恭喜你!");
}
else {
System.out.println("未及格,需要补考!");
}
System.out.println("本次查询结束!");
}
}
如果将浮点数是否相等来作为if的条件,不能用==来判断浮点是否相等,因为由于浮点数是不能精确表示的:
public class bijiao {
public static void main(String[] args) {
double x=1-9.0/10;
if(x==0.1) {
System.out.println("X的值为0.1");
}
else
{
System.out.println("X的值不为0.1");
}
//运行结果x的值不为0.1
}
}
所以一般用利用差值小于某个临界值来判断:
public class bijiao {
public static void main(String[] args) {
double x=1-9.0/10;
if(Math.abs(x-0.1)<0.00001) {
System.out.println("X的值为0.1");
}
else
{
System.out.println("X的值不为0.1");
}
}//运行结果:x的值为0.1
引用类型数据对比
在Java中,判断值类型的变量是否相等,可以使用 ==
运算符。但是,判断引用类型的变量是否相等,==
表示“引用是否相等”,或者说,是否指向同一个对象。例如,下面的两个String类型,它们的内容是相同的,但是,分别指向不同的对象,用==
判断,结果为false:
public class bijiao {
public static void main(String[] args) {
String s1="hello";
String s2="HELLO".toLowerCase();
System.out.println(s1);
System.out.println(s2);
if(s1==s2) {
System.out.println("s1=s2");
}
else
{
System.out.println("s1!=s2");
}
}//运行结果:s1!=s2
}
要判断引用类型的变量内容是否相等,必须使用equals()
方法:
public class bijiao {
public static void main(String[] args) {
String s1="hello";
String s2="HELLO".toLowerCase();
System.out.println(s1);
System.out.println(s2);
if(s1.equals(s2)) {
System.out.println("s1=s2");
}
else
{
System.out.println("s1!=s2");
}
}//运行结果:s1=s2
}
注意:执行语句s1.equals(s2)
时,如果变量s1
为null
,会报NullPointerException
:
public class Main {
public static void main(String[] args) {
String s1 = null;
if (s1.equals("hello")) {
System.out.println("hello");
}
}
}
要避免NullPointerException
错误,可以利用短路运算符&&:
public class Main {
public static void main(String[] args) {
String s1 = null;
if (s1 != null && s1.equals("hello")) {
System.out.println("hello");
}
}
}
switch多重选择
除了if
条件判断语句之外,还提供了switch
语句判断,是根据某个表达式的结果,分别去执行不同的分支。
例如在游戏中:
1.出剪刀
2.出石头
3.出布
这时switch
就派上用场了。
switch
是根据switch(表达式)
表达式来计算结果跳转到case
语句,然后执行后续语句,直到遇到break
结束执行。
import java.util.Scanner;
public class Switch {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入您的选择:");
int option=scanner.nextInt();
switch (option) {
case 1:
System.out.println("selcet 1");
break;
case 2:
System.out.println("selcet 2");
break;
case 3:
System.out.println("selcet 3");
break;
}
}
}
如果输入99,程序不会被执行,这是我们就需要使用default
,当没有匹配到选择的条件则执行default
下面的语句。
import java.util.Scanner;
public class Switch {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
System.out.println("请输入您的选择:");
int option=scanner.nextInt();
switch (option) {
case 1:
System.out.println("selceted 1");
break;
case 2:
System.out.println("selceted2");
break;
case 3:
System.out.println("selceted 3");
break;
default:
System.out.println("no selceted");
}
}
}
如果把switch
语句翻译成if
语句,那么上述的代码相当于:
if (option == 1) {
System.out.println("selected 1");
} else if (option == 2) {
System.out.println("selected 2");
} else if (option == 3) {
System.out.println("selected 3");
} else {
System.out.println("no selected");
}
对于多个==判断的情况,使用switch
结构更加清晰。
同时注意,上述“翻译”只有在switch
语句中对每个case
正确编写了break
语句才能对应得上。不可以漏写break
要不然会出现不是预期的运行结果。
使用switch语句时,只要保证有break,case的顺序不影响程序逻辑:
switch (option) {
case 3:
...
break;
case 2:
...
break;
case 1:
...
break;
}
switch
语句还可以匹配字符串。字符串匹配时,是比较“内容相等”。例如:
public class Main {
public static void main(String[] args) {
String fruit = "apple";
switch (fruit) {
case "apple":
System.out.println("Selected apple");
break;
case "pear":
System.out.println("Selected pear");
break;
case "mango":
System.out.println("Selected mango");
break;
default:
System.out.println("No fruit selected");
break;
}
}
}
while循环
循环语句就是就是计算机根据循环条件做出计算,符合循环条件程序执行,不符合循环条件则退出循环。
例如计算1到100的累加运算:
public class Whlie {
public static void main(String[] args) {
int sum=0;//累加的和,初始值为0
int n=1;
while (n<=100) {//循环条件是n<=100
sum=sum+n;//将累加的和赋给sum
n++;//n自身加1
}
System.out.println(sum);//输出结果5050
}
}
java
提供的whlie
条件循环,语法如下:
while(循环条件){
循环语句
}
//继续执行后续代码
注意到while
循环是先判断循环条件,再循环,因此,有可能一次循环都不做。
如果循环条件永远满足,那这个循环就变成了死循环。死循环将导致100%的CPU占用,用户会感觉电脑运行缓慢,所以要避免编写死循环代码。
public class Main {
public static void main(String[] args) {
int sum = 0;
int n = 1;
while (n > 0) {
sum = sum + n;
n ++;
}
System.out.println(n); // -2147483648
System.out.println(sum);
}
}
表面上看,上面的while循环是一个死循环,但是,Java
的int
类型有最大值,达到最大值后,再加1会变成负数,结果,意外退出了while
循环。
do while循环
在Java
中,while
循环是先判断循环条件,再执行循环。而另一种do while
循环则是先执行循环,再判断条件,条件满足时继续循环,条件不满足时退出。它的用法是:
do{
//执行循环语句
}
while(循环条件);
可见,do while
循环会至少循环一次。
我们把对1到100的求和用do while
循环改写一下:
public class DO {
public static void main(String[] args) {
int sum=0;
int n=0;
do {
sum=sum+n;
n++;
}while(n<=100);
System.out.println(sum);
}
}
for循环
除了while
和do while
循环,Java
使用最广泛的是for
循环。
for
循环的功能非常强大,它使用计数器实现循环。for
循环会先初始化计数器,然后,在每次循环前检测循环条件,在每次循环后更新计数器。计数器变量通常命名为i
。
我们用for
循环来改写一下1到100的累加:
public class Main {
public static void main(String[] args) {
int sum = 0;
for (int i=1; i<=100; i++) {
sum = sum + i;
}
System.out.println(sum);
}
}
在for
循环执行前,会先执行初始化语句int i=1
,它定义了计数器变量i并赋初始值为1
,然后,循环前先检查循环条件i<=100
,循环后自动执行i++
,因此,和while
循环相比,for
循环把更新计数器的代码统一放到了一起。在for
循环的循环体内部,不需要去更新变量i
。
因此,for
循环的用法是:
for (初始条件; 循环检测条件; 循环后更新计数器) {
// 执行语句
}
如果我们要对一个整型数组的所有元素求和,可以用for
循环实现:
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
int sum = 0;
for (int i=0; i<ns.length; i++) {
System.out.println("i = " + i + ", ns[i] = " + ns[i]);
sum = sum + ns[i];
}
System.out.println("sum = " + sum);
}
}
上面代码的循环条件是i<ns.length
。因为ns
数组的长度是5
,因此,当循环5
次后,i的值被更新为5
,就不满足循环条件,因此for
循环结束。
注意for
循环的初始化计数器总是会被执行,并且for
循环也可能循环0
次。
使用for
循环时,千万不要在循环体内修改计数器!在循环体中修改计数器常常导致莫名其妙的逻辑错误。对于下面的代码:
public class Main {
public static void main(String[] args) {
int[] ns = { 1, 4, 9, 16, 25 };
for (int i=0; i<ns.length; i++) {
System.out.println(ns[i]);
i = i + 1;//修改了计数器i
}
}
}
虽然不会报错,但是,数组元素只打印了一半,原因是循环内部的i = i + 1
导致了计数器变量每次循环实际上加了2
(因为for
循环还会自动执行i++
)。因此,在for
循环中,不要修改计数器的值。计数器的初始化、判断条件、每次循环后的更新条件统一放到for()
语句中可以一目了然。
break与continue
无论是while
循环与for
循环都可以使用特殊的语句break
与continue
语句。
break
在循环过程中,可以使用break
跳出循环,例如下面例子:
public class Break {
public static void main(String[] args) {
int sum=0;
for (int i =1; ;i++) {
sum=sum+i;
if (i==100) {
break;
}
}
System.out.println(sum);
}
}
使用for循环计算从1到100时,我们并没有在for()中设置循环退出的检测条件。但是,在循环内部,我们用if判断,如果i==100,就通过break退出循环。
因此,break语句通常都是配合if语句使用。要特别注意,break语句总是跳出自己所在的那一层循环。例如:
public class Test {
public static void main(String[] args) {
for(int i=0;i<=10;i++) {
System.out.println("i="+i);
for(int j=0;j<=10;j++)
{
System.out.println("j="+j);
if (j>=i)
{
break;
}
}
//break跳到这里
System.out.println("Breaked");
}
}
}
上面试两个for
循环的嵌套。因为break
于内层的for
循环,因此程序它会跳出内层的for
循环,但不会跳出外层的for
循环。
continue
break是会跳出当前循环,再也不会执行循环了。而continue不同的是,提前结束本次循环,然后继续执行接下次循环。来看一个例子:
public class Test1 {
public static void main(String[] args) {
int sum=0;
for(int i=0;i<=10;i++) {
System.out.println("begin i ="+i);
if(i%2==0) {
continue;//continue跳出本次循环
}
sum=sum+i;
System.out.println("end i ="+i);
}
System.out.println(sum);
}
}
观察运行结果可以发现continue
的效果,当i为奇数时循环执行完整,当i为偶数时就会只执行"begin i ="
句语句,而不会执行"end i ="
这句语句。
在多层嵌套的循环语句中,continue
也只是跳出本层嵌套循环的当前循环。