Java第三课. 流程控制
1. 流程控制:
1.1 条件结构:
1.1.1 If结构/if-else结构:
If(表达式/ boolean的值){
执行的语句
}
表达式的值: true/false //只有当表达式结果为true才执行{}里的内容
//if后的条件表达式返回值必须是boolean类型,不能是0或1
If(表达式){
执行的语句
}else{
}
int i;
System.out.println("请输入一个整数:");
Scanner scanner=new Scanner(System.in);
i=scanner.nextInt();
//1.条件分支语句: if
if(i>20) {
System.out.println("i的值大于20");
}
//2.if...else
if (i>20) {
System.out.println("i的值大于20");
}else {
System.out.println("i的值小于等于20");
}
1.1.2多重if:
if(判断语句1){ // if/else if/else,else if语句可以多个
执行语句1;
}else if(判断语句2){
执行语句2;
} ……
else if(判断语句n){
执行语句n;
}
else{
}
//3.if... else if... else
//应用场景:多重if适用于多个条件,只有一个条件会满足(可能一个条件都不满足,else省略的情况)
//else可以省略
//定义变量存储年龄
//0-18是一个区间,所以用&&,连接多个条件
int age;
System.out.println("请输入年龄:");
Scanner scanner=new Scanner(System.in);
age=scanner.nextInt();
if (age>55) {
System.out.println("老年人");
}else if(age>=30) {
System.out.println("中年人");
}else if (age>=18) {
System.out.println("青年人");
}else if(age<18 && age>=0) {
System.out.println("少年");
}else {
System.out.println("年龄不能为负数");
}
scanner.close();
1.1.3嵌套的if:
表示的是一种递进的关系
if(表达式){
if(){
}
}else{
if(){
}else{
}
}
1.1.4 练习:
//1. 使用if完成三个数字中的最大值
public class Test_if {
public static void main(String[] args) {
System.out.println("请输入三个数字:");
Scanner scanner=new Scanner(System.in);
int a=scanner.nextInt();
int b=scanner.nextInt();
int c=scanner.nextInt();
//方式一
if (a>b) {
//此时a是ab中最大值
//拿a再去跟c比较就可以了
if (a>c) {
System.out.println("最大值是a:"+a);
}else {
//c>a
System.out.println("最大值是c:"+c);
}
}else {
//此时b是ab中最大值
//拿b再去跟c比较就可以了
if (b>c) {
System.out.println("最大值是b:"+b);
}else {
//c>b
System.out.println("最大值是c:"+c);
}
}
//方式2: 0 3 9
int max=a;//max=0
if (max<b) {
max=b;
}
if (max<c) {
max=c;
}
System.out.println("最大值:"+max);
scanner.close();
}
}
//2. 使用嵌套if与多重if实现从控制台输入成绩(0-100)
90-100:奖励Iphonex一部,再接再厉
80-90:奖励Ipad一部,再接再厉!
60-80:奖励棒棒糖一枚,要努力咯,距离双打不远了
0-60:混合双打一顿,要努力咯~
不满足以上条件:输入有误
public class Test_if {
public static void main(String[] args) {
System.out.println("请输入成绩:");
Scanner scanner=new Scanner(System.in);
int score=scanner.nextInt();
//区间0~100
if (score>=0 && score<=100) {
//判断成绩
if (score>=90) {
System.out.println("奖励Iphonex一部,再接再厉");
}else if (score>=80) {
System.out.println("奖励Ipad一部,再接再厉!");
}else if (score>=60) {
System.out.println("奖励棒棒糖一枚,要努力咯,距离双打不远了");
}else {
System.out.println("混合双打一顿,要努力咯~");
}
}else {
System.out.println("输入成绩有误~");
}
}
}
//3. 使用多重if来计算某年中某个月份的天数(经典);
import java.util.Scanner;
public class Test_if {
public static void main(String[] args) {
System.out.println("请输入年份和月份:");
Scanner scanner=new Scanner(System.in);
int year=scanner.nextInt();
int month=scanner.nextInt();
if (month==1 || month==3 || month==5 || month==7 || month==8 || month==10 || month==12) {
System.out.println("该月有31天!");
}else if (month==4 || month==6 || month==9 || month==11 ) {
System.out.println("该月有30天!");
}else if (month==2) {
//是否是闰年->嵌套
if (year % 4==0 && year%100 != 0 || year%400==0) {
System.out.println("该月有29天!");
}else {
System.out.println("该月有28天!");
}
}else {
System.out.println("输入的月份不在1~12范围");
}
scanner.close();
}
}
//因为闰年和平年的区别在与二月的天数不同,所以先对月份进行判断,然后在二月的时候进行嵌套if判断,这题用switch case更简单
1.1.5 switch/case
1.有时候分支是根据常量值进行判断的,这时候虽然可以使用if/else来实现,但
是用switch/case更为清晰;
2.在case语句块中用break语句控制跳出switch语句;
switch(表达式) {
case value: //value指的是表达式可能出现的值,只能是常量,必须是固定值
执行语句;
break;
.......... //可以放多个case
default:
语句;
break;
}
switch/case中可以有break语句,也可以没有break,多数情况都使用break语句;没有break的情况下,执行语句之后的语句都会输出;
public class Test_switch {
public static void main(String[] args) {
System.out.println("请输入1个数字:");
Scanner scanner=new Scanner(System.in);
int a=scanner.nextInt();
switch(a) {
case 1:
case 2:
System.out.println("a==2");
break;
default:
System.out.println("其他情况~");
break;
}
String string="A";
switch(string) {
case "A":
System.out.println("a==A");
break;//结束switch
case "B":
System.out.println("a==B");
break;
default:
System.out.println("其他情况~");
break;
}
scanner.close();
}
}
1.1.6 switch/case表达式的要求
switch/case中的表达式叧能使用规定的基本数据类型,JDK1.5前可以使用:
• 基本数据类型 byte
• 基本数据类型 short
• 基本数据类型 int
• 字符型 char
不能使用:
• 基本数据类型 float double long boolean
• JDK5之后,switch表达式类型新增加支持:枚举 enum
• JDK7之后,switch表达式类型新增加支持:String
有时候安装的是JDK7,Eclipse还是不支持String,这个时候要看一下Eclipse支持的编译版本,如果Eclipse只支持到1.6的情况,你安装了1.7也木有用
1.1.7练习
//1:通过switch..case语句实现:从控制台接收年份和月份,输出该月有多少天
import java.util.Scanner;
public class Test_switch {
public static void main(String[] args) {
System.out.println("请输入年份和月份:");
Scanner scanner=new Scanner(System.in);
int year=scanner.nextInt();
int month=scanner.nextInt();
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
System.out.println("该月有31天~");//当case后面的执行语句相同可以省略
break;
case 4:
case 6:
case 9:
case 11:
System.out.println("该月有30天~");
break;
case 2:
//是否是闰年
if (year % 4==0 && year%100 != 0 || year%400==0) {
System.out.println("该月有29天!");
}else {
System.out.println("该月有28天!");
}
break;
default:
System.out.println("输入月份有误~");
break;
}
scanner.close();
}
}
2:通过switch..case语句实现菜单
用户输入1 注册
用户输入2 登录
用户输入3 退出
import java.util.Scanner;
public class Test11_switch {
public static void main(String[] args) {
System.out.println("请输入功能 1注册 2登录 3退出");
Scanner scanner=new Scanner(System.in);
int flag=scanner.nextInt();
switch (flag) {
case 1:
System.out.println("注册");
//调用注册方法
break;
case 2:
System.out.println("登录");
//调用登录方法
break;
case 3:
System.exit(0);//退出程序
break;
default:
break;
}
scanner.close();
}
}
1.1.8 Switch-case和多重if有什么异同?
Java语言中的流程控制有两种,分别是if/else和switch/case;
两者都可以进行多个条件的判断;
语法上的不同, Switch-case它只能判断等值的情况,而多重if可以判断等值也判断区间;
2. 循环结构:
1. 循环目的:用来处理有规律反复出现的事情,解决重复的操作
2. 实现循环必须确认得事情: ①重复的操作 ②结束循环的条件
Java语言中的有三种循环语句,分别是for、while、do while;
2.1 for循环
for(表达式1;表达式2;表达式3) {
循环体 :需要重复执行的代码
//当表达式2为true才执行
//表达式1是定义变量,赋予初始值--->循环开始条件 int a=1;
//表达式2是条件判断,要么true,要么false-->循环的结束条件 a<=10;
//表达式3是变量的变化,可以是变量自加或自减-->循环变量的变化 a++;
}
执行过程:
表达式1->(表达式2->循环体->表达式3)->(表达式2->循环体->表达式3)->(表达式2->循环体->表达式3)->(表达式2->循环体->表达式3).......
执行过程:
先执行表达式1,只执行1次,然后执行表达式2的判断,如果为true,则执行循环体内的代码,如果为false,则循环体内的代码不执行,结束只有表达式2为true,循环体才执行,再执行表达式3,然后再回来判断条件(表达式2);
public class Test_for {
public static void main(String[] args) {
for(int i=1;i<=10;i++) {
System.out.println(i+"忘了");
}
}
}
2.1.1 用for循环来解决一些数学问题:
1. 1+2+3+…+123:
分析: 循环要执行多少次? 123需要从1开始 2 3 ….123,我需要将每次的变量都累加起来;
i=1 sum=0+1
i=2 sum=0+1+2
i=3 sum=0+1+2+3
i=4 sum=0+1+2+3+4
public class Test_for {
public static void main(String[] args) {
int sum=0;
for(int i=1;i<=123;i++) {
//循环体
//将i的值累加
sum+=i;//sum=sum+i;//sum=0+1;sum=(0+1)+2;sum=(0+1+2)+3
}
//在循环外部输出最终结果
System.out.println(sum);
2. 求100以内的偶数和:
int sum1=0;
for(int i=1;i<=100;i++) {
//循环体
//如果是偶数就将i的值累加
if (i%2==0) {
sum1+=i;
}
}
//在循环外部输出最终结果
System.out.println(sum1);//2550
3. 求100以内的奇数和:
int sum2=0;
for(int i=1;i<=100;i++) {
//循环体
//如果是奇数就将i的值累加
if (i%2==1) {
sum2+=i;
}
}
//在循环外部输出最终结果
System.out.println(sum2);//2500
}
}
2.1.2 练习
1. 求1+2+3.+100和,要求跳过所有的3的倍数和5的倍数;
public class Test07_for {
public static void main(String[] args) {
int sum=0;
for (int i = 1; i <=100; i++) {
if (i%3!=0 && i%5!=0) {
sum+=i;
}
}
System.out.println(sum);//2632
2.求100-1000以内的所有水仙花 (153=1*1*1+5*5*5+3*3*3)
for (int i = 100; i <1000; i++) {
//将个位 十位 百位的值取出来,求立方
int g=i%10;
int s=i/10%10;
int b=i/100;
if (g*g*g+s*s*s+b*b*b==i) {
System.out.println("水仙花数:"+i);
}
}
3.1!+2!+3!+….+7!的结果是多少?
//1+1*2+1*2*3+....1*2*3*4*5*6*7
int sum1=1;
int sum2=0;
for (int i =1; i <=7; i++) {
sum1*=i;//sum1=1;sum1=1*2;sum1=1*2*3;sum1=1*2*3*4
//将sum1累加起来
sum2+=sum1;
}
System.out.println(sum2);//5913
}
}
for(;😉{} 这样的语句是死循环
2.2 跳出循环的关键字:
控制循环的关键字:
break: 跳出循环结构 ;向外跳出一层;
continue:终止当前次循环,尝试进行下一次循环;
public class Test_break {
public static void main(String[] args) {
for (int i = 1; i <=5; i++) {
if (i==3) {
//break;//跳出循环 1 2
continue;
}
System.out.println(i); //1 2 4 5
}
}
}
public class Test_break2 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
for (int i = 1; i <=100; i++) {
System.out.println("请问你吃了吗?(yes/no)");
String ans=scanner.next(); //next()代表String类型
//如果输入的是yes,循环结束
if ("yes".equals(ans)) {
break;
}else {
//否则
System.out.println("干饭了!");
}
}
System.out.println("好的");
scanner.close();
}
}
import java.util.Scanner;
public class Test_continue {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
for (int i = 1; i <=100; i++) {
System.out.println("请问你吃了吗?(yes/no)");
String ans=scanner.next();
//如果输入的是yes,循环结束
if ("yes".equals(ans)) {
//break;
continue;
}
System.out.println("干饭了!"+i);
}
System.out.println("好的");
scanner.close();
}
}
请问你吃了吗?(yes/no)
no
干饭了!1
请问你吃了吗?(yes/no)
no
干饭了!2
请问你吃了吗?(yes/no)
no
干饭了!3
请问你吃了吗?(yes/no)
yes
请问你吃了吗?(yes/no)
no
干饭了!5
请问你吃了吗?(yes/no)
在多重循环时,continue默认是继续当前的循环;如果希望continue继续的是外层循环,用continue 标号;语句继续指定的循环;
loop1: for(int i=0;i<5;i++){
loop2: for(int j=0;j<6;j++){
//当i==j时,继续i循环
if(i==j){
continue loop1; //continue loop1;语句继loop1标记的循环,即i层循环;
}
System.out.println("i="+i+" j="+j);
}
System.out.println("结束i循环的第"+i+"次循环");
}
System.out.println("结束i循环");
break 语句在多重循环中同理操作;
2.3 while循环
先判断条件,如果条件为真,执行循环体,如果为假,跳过循环;
public class Test_while {
public static void main(String[] args) {
System.out.println("*******while 先判断条件,再执行循环体**********");
int i=1;
while(i>1) {
i++;
System.out.println("i:"+i); //不会执行
}
}
}
2.3 do while循环
public class Test_while {
public static void main(String[] args) {
System.out.println("*******do while 先执行循环体,再判断条件**********");
int j=1;
do {
j++;
System.out.println("j:"+j); //死循环
}while(j>1) ;
}
}
2.4 Foreach循环:
• JDK5增加了增强for循环,能够方便地对数组(以及以后学习的集合)进行迭代;
• foreach并不是一个关键字,习惯上将这种特殊的for语句格式称之为“foreach”语句。从英文字面意思理解foreach也就是“for 每一个”的意思。实际上也就是这个意思。
foreach 的语句格式:
for(元素类型t 元素变量x : 遍历对象obj){
引用了x的java语句;
}
public class Test_foreach {
public static void main(String[] args) {
//创建一个数组
//new
int[] arr=new int[] {11,2,3,4,5};
System.out.println("*****foreach(for)*****");
//使用foreach
//数据类型 变量名: 数组名(集合)
for(int i:arr) {
System.out.println(i);
}
}
}
2.4 嵌套循环:
2.4.1 基本结构:
在一层循环中,还包含了另外一层的循环,这种结构称为嵌套循环;
2.4.2 九九乘法表:
public class Test_for {
public static void main(String[] args) {
//外循环控制的是行的打印
for(int i=1;i<=9;i++) {
//内循环 控制的是每行打印的表达式的个数
for(int j=1;j<=i;j++) {
System.out.print(j+"*"+i+"="+(i*j)+"\t");
}
//换行
System.out.println();
}
}
}
关于 string 的1个问题(常见面试题)
1.String s1 = "a";与String s1 = new String("a");有什么区别?
String s1 = "a";
String s2 = "a";
System.out.println("s1 == s2 is " + (s1==s2));显示结果为true;
String s1 = new String("a");
String s2 = new String("a");
System.out.println("s1 == s2 is " + (s1==s2));显示结果false;
System.out.println(s1.equals(s2))结果为 true;
参考(两种思考):
//第一种
在判断两个 String 是否相等的时应该用 equals()函数,因为==只能检测到两个 String 是否是同一地址(公用),所以 String s1 = "a";String s2 = "a"是 true;jvm 会分配一块地址给"a",然后然s1和s2都指向这块地址(“a”放在一个地址里 s1和s2同指向一个地址)
在 String s1 = new String("a");
String s2 = new String("a");
jvm会给s1和s2各分配一块地址,不是在同一地址里;
//第二种
String s1 = "a";内存会去查找永久代(字符串常量池) ,如果没有的话,在永久代中重开辟一块儿内存空间,把地址付给栈指针,如果已经有了"a"的内存,直接把地址赋给栈指针;String s1 = "a";String s2 = "a";因为他们的地址都相等,因此只在常量池中有一份内存空间,地址全部相同;
String s1 = new String("a");是根据"a"这个 String 对象再次构造一个 String 对象;在堆中从新 new 一块儿内存,把指针赋给栈,将新构造出来的 String 对象的引用赋给 str。 因此 只要是new String(),则栈中的地址都是指向最新的new出来的堆中的地址,
“”==“” 是判断地址的,当然不相同;
至于equals,String 类型重写了 equals()方法,判断值是否相等,明显相等,因此 equals 是相等的;
String s = new String(“hello”)会创建2(1)个对象,String s = “hello”创建1(0)个对象。
注:当字符串常量池中有对象hello时括号内成立!
2.5 循环练习:
1. 使用 while 循环或者 dowhile 循环实现买单
实现不间断的输入商品编号(int)、价格、数量,直到用户选择结束买单为止,显示出购买的总金额。
提示:设置一个标杆作为循环的条件
import java.util.Scanner;
public class Test01 {
public static void main(String[] args) {
//单个商品的总金额
float sum=0;
//总金额
float sum1=0;
//商品名称
String goodsName="";
//价格
float goodsprice=0;
//数量
int goodsCount=0;
//进入购买状态
String isOK="Y";
//结果
String rs="商品列表";
Scanner sc=new Scanner(System.in);
while("Y".equalsIgnoreCase(isOK)) {
System.out.println("请输入商品名称:");
goodsName=sc.next();
System.out.println("请输入商品价格:");
goodsprice=sc.nextFloat();
System.out.println("请输入商品数量:");
goodsCount=sc.nextInt();
//计算金额
sum=goodsCount*goodsprice;
//商品列表的拼接
rs+=""+goodsName;
//设置循环结束的条件
System.out.println("是否继续买单? Y继续");
isOK=sc.next();
System.out.println(goodsName+":金额:"+sum);
//金额的累加
sum1+=sum;
}
//输出总金额
System.out.println(rs+":总金额="+sum1);
sc.close();
}
}
2. 从键盘输入10个整数,当输入的整数是100时,结束输入 break
Scanner scanner=new Scanner(System.in);
int num;
//输入10个整数->执行10次循环
for(int i=1;i<=10;i++) {
System.out.println("请输入第"+i+"个整数:");
num=scanner.nextInt();
if (num==100) {
System.out.println("over~");
break;//结束循环
}
}
scanner.close();
4.公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一 值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
public class Test05 {
public static void main(String[] args) {
// 1. 公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:
// 鸡翁一 值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
//方法一
for (int i = 0; i <=20 ; i++) {
for (int j = 0; j <=33; j++) {
for (int k = 0; k <=100; k++) {
if (i*5+j*3+k/3==100 && k%3==0 && i+j+k==100) {
System.out.println("鸡翁、鸡母、鸡雏分别为:"+i+","+j+","+k+"只");
}
}
}
}
//方法二
for (int i = 0; i <=20 ; i++) {
for (int j = 0; j <=33; j++) {
int k=100-i-j;
if (i*5+j*3+k/3==100 && k%3==0 && i+j+k==100) { //k只能为3的倍数,因为k/3的结果取整,现实中是除不尽3的
System.out.println("鸡翁、鸡母、鸡雏分别为:"+i+","+j+","+k+"只");
}
}
}
}
}
循环小结
• Java语言中有for、while、do while三种循环;
• while循环可能会循环0次,而do while循环至少循环1次;
• continue 用来继续下一次循环,该语句后的循环体中的语句丌再被执行;
• break 用来终止当前层的循环,该语句执行后跳出本层循环;
• 在for、while、do while前可以加标号,标号必须符合标识符的命名规范;
break/continue后可以加上标号,从而控制操作的具体循环;
• 增强 for 循环是 JDK5 增加的特性,可以用来迭代数组及集合;集合后续学习;