java06 类型转换 流程控制 作业

1 类型转换

java中的=号赋值操作,需要=号俩边的类型一致,也就是=号右边的数据的类型要和=号左边的变量的类型保持一致,如果不一致,那么就需要做类型的转换,分为隐式转换和显示转换。

隐式转换也称为自动转换。

显示转换也称为强制转换/手动转换。

1.1 基本类型

隐式转换(Implicit),也是自动转换。

在JVM运行期间,只要满足条件,就可以自动完成类型转换的过程。一般是数据范围比较小的,自动就可以转换为数据范围比较大的类型(基本类型)。

例如,

byte a = 1;
int b = a; //注意,这里在运行期间,就自动完成了转换的过程

显示转换(explicit),也是手动转换/强制转换。(简称:强转,有风险)

编译器发现类型无法自动转换的情况,就会编译报错,这时候我们确认无误后,就可以进行类型强制转换。

但是这里是存在一定风险的,在基本类型数据中,这个风险主要是可能数据有损失,在引用类型中,将来在运行这个类型转换代码的时候,有可能会抛出类型转换异常。

例如,

int a = 100;
//编译报错,因为a是int类型,b是byte
//把32位int数据,赋值给8位的变量b
//把一个范围大的数据,赋给一个范围小的变量
//这时候是不允许的,也无法类型自动转换。
byte b = a;

//编译通过,自己手动进行了类型转换
//对于基本类型,强制转换就是把多余的位给抹去
//所以这时候可能对数据的值,造成影响
byte b = (byte)a;

注意,浮点型数据,如果强行转换为整型,小数部分就需要全部抹去。

例如,生成[0,9]直接的随机数(整数)

//Math.random()返回[0,1)的随机数,类型是double
double random = Math.random()*10;
int a = (int)random;
System.out.println(a);

1.2 引用类型

隐式转换(Implicit)

例如,

Student s = new Student();
Object o = s;//特点:子类类型的变量,可以自动转为(隐式)父类类型

//上面俩句代码可以合成这一句代码,其实就是把中间变量s给去掉了。
Object o = new Student();

显示转换(explicit)

例如,

Object o = new Student();
Student s = (Student)o;//特点:父类类型的变量,需要强制转为(显式)子类类型

思考1,一个子类型的变量,一定能自动转为它的父类型么?

思考2,一个父类型变量,一定能强制转成它的一个子类型么?

可以结合着instanceof关键字进行考虑。

2 流程控制

2.1 if

格式1

if(比较表达式) {
				语句体;
}
/*
   先计算比较表达式的值,看其返回值是true还是false。
   如果是true,就执行语句体;
   如果是false,就不执行语句体;

*/

例如,

int a = 10;
if(a%2==0){
    System.out.println("变量a的值为偶数");
}

if语句注意事项:

  • 比较表达式无论简单还是复杂,结果必须是boolean类型
  • if语句控制的语句体如果是一条语句,大括号可以省略,建议不要省略
  • 如果是多条语句,就不能省略。

格式2

if(比较表达式) {
     语句体1;
} else {
	语句体2;
}
/*
	首先计算比较表达式的值,看其返回值是true还是false。
	如果是true,就执行语句体1;
	如果是false,就执行语句体2

*/

例如,

int a = 10;
if(a%2==0){
    System.out.println("变量a的值为偶数");
}
else{
    System.out.println("变量a的值为奇数");
}

if和else形成了一个组合,特点就是如果if中的代码执行了,那么else的代码就不执行,如果if中的代码没执行,那么else中的代码就会执行。也就是if和else这俩个语句中的代码,【一定】是有唯一的一个执行,而另一个不执行。

例如,

int a = 10;
if(a%2==0){
    System.out.println("变量a的值为偶数");
}
if(a%2==1){
    System.out.println("变量a的值为奇数");
}

第一个if条件无论是true还是false,第二个if条都会继续判断,这个逻辑和if-else是不同的

格式3

if(比较表达式1) {
 语句体1;
}else if(比较表达式2) {
 语句体2;
}else if(比较表达式3) {
 语句体3;
}
...
else {
 语句体n+1;
}


/*
	执行流程
	先计算比较表达式1看其返回值是true还是false,
  		如果是true,就执行语句体1,if语句结束。
  		如果是false,接着计算比较表达式2看其返回值是true还是false,

  	如果是true,就执行语句体2,if语句结束。
  	如果是false,接着计算比较表达式3看其返回值是true还是false,

  	如果都是false,就执行语句体n+1。

	注意事项:
		最后一个else可以省略,但是建议不要省略,可以对范围外的错误值提示 
*/

例如,

int a = 10;
if(a>90){
    System.out.println("优秀");
}else if(a>80){
    System.out.println("良好");
}else if(a>70){
    System.out.println("中等");
}else if(a>60){
    System.out.println("及格");
}else{
    System.out.println("不及格");
}

从上到下依次判断,有一个判断为true执行了代码,那么后续判断都不再执行,如果判断都为false,则执行else语句代码

例如:实现一个方法,方法调用完后会返回一个问候的语句,如果是8点12点之间,那么就返回早上好,如果是12点14点,则返回中午好,如果是14点~18点,则返回下午好,其他情况,返回晚上好。

public String sayHello(int hour){
    String message;

    if(hour>=8 && hour<12){
        message = "早上好";
    } else if(hour>=12 && hour<14){
        message = "中午好";
    }
    else if(hour>=14 && hour<18){
        message = "下午好";
    }
    else{
        message = "晚上好";
    }

    return message;
}

例如:实现一个方法,方法需要传一个参数,表示年份,方法调用完后会返回一个boolean值,表示这个年份是不是闰年。

闰年判断标准:以下条件满足一个,就是闰年

  • 能被4整除,但是不能被100整除
  • 能被400整除
public boolean isLeapYear(int year){
    boolean flag = false;

    if((year%4==0 && year%100!=0) || year%400==0){
        flag = true;
    }

    return flag;
}

//这俩方法中的代码是等价的

public boolean isLeapYear(int year){
	return (year%4==0 && year%100!=0) || year%400==0;
}


2.2 switch

switch语句和if很类似,都是用来判断值是否相等,但是switch默认只支持byte、short、int、char这四种类型的比较,JDK8中也允许String类型的变量做对比。

使用switch来完成的功能,同样可以使用if来完成,但是使用if完成的功能,使用switch不一定能完成。

case后面只能是常量,不能是变量,而且,多个case后面的值不能出现相同的

default可以省略,但是不建议,因为它的作用是对不正确的情况给出提示。

例如,

int mode = 0;//0 1 2 3

switch(mode){
    case 0:{
        System.out.println("默认模式开启");
        break;
    }

    case 1:{
        System.out.println("手动模式开启");
        break;
    }

    case 2:{
        System.out.println("自动模式开启");
        break;
    }

    case 3:{
        System.out.println("智能模式开启");
        break;
    }

    default:{
        System.out.println("模式选择错误!!");
    }

}

假如mode本次的值是0,那么case 0 这种情况就成立了,然后打印指定语句,再执行break,接着退出整个switch语句。

也就是说case 1 2 3 default这几种情况的代码就不再判断也不再执行。这一切都是因为执行了break。

如果没写break,那么这时候就会变成另外一种情况:

int mode = 0;//0 1 2 3
		
switch(mode){

    case 0:{
        System.out.println("默认模式开启");
    }

    case 1:{
        System.out.println("手动模式开启");
    }

    case 2:{
        System.out.println("自动模式开启");
    }

    case 3:{
        System.out.println("智能模式开启");
    }

    default:{
        System.out.println("模式选择错误!!");
    }

}

这个代码中的break全都去掉了

假设本次mode的值还是0,那么case 0成立之后,现在执行里面的代码, 打印指定语句。

由于这时候没有break,然后代码会继续往下执行,并且不会再做case 1 2 3的判断了,而是直接执行case 1 2 3中的代码,也包含执行default中的代码,所以最后的输出结果为:

​ 默认模式开启
​ 手动模式开启
​ 自动模式开启
​ 智能模式开启
​ 模式选择错误!!

这种情况,就是因为代码中没有写break的原因。

例如,实现一个方法,方法需要一个int类型参数,方法中可以把这个数字转换为对应的星期几,例如 0对应星期天,1对应星期一,方法最后需要把转换的结果返回。

public String getDayStr(int day){
    String result;		

    switch(day){
        case 0:{
            result = "星期天";
            break;
        }

        case 1:{
            result = "星期一";
            break;
        }

        case 2:{
            result = "星期二";
            break;
        }

        case 3:{
            result = "星期三";
            break;
        }

        case 4:{
            result = "星期四";
            break;
        }

        case 5:{
            result = "星期五";
            break;
        }

        case 6:{
            result = "星期六";
            break;
        }

        default:{
            result = "参数有误,参数day的值可以在[0,6]之间";
        }
    }

    return result;
}

例如,实现一个方法,方法需要俩个int类型参数,一个表示年份,一个表示月份,方法的返回值也是int,返回值的含义是指定年份指定月份一共有多少天

public int getDayOfMonth(int year,int month){
    IfTest t = new IfTest();
    int num = 31;

    switch(month){
        case 4:
        case 6:
        case 9:
        case 11:{
            num = 30;
            break;
        }
        case 2:{
            num = ( t.isLeapYear(year)?29:28 );
        }
    }

    return num;
}

注意,isLeapYear这方法是调用的IfTest类中之前写好的方法

关于switch有几个问题:

break可以省略吗?

  • 最后一个可以省略,其他最好不要省略
  • 会出现一个现象:case穿透。
  • 最终我们建议不要省略

default一定要在最后吗?

  • 不是,可以在任意位置。但是建议在最后。

switch语句的结束条件

  • 遇到break就结束了
  • 执行到switch的右大括号就结束了

练习

int x = 2;
int y = 3;
switch(x){
    default:
        y++;
        break;
    case 3:
        y++;
    case 4:
        y++;
}
System.out.println("y="+y);
int x = 2;
int y = 3;
switch(x){
    default:
        y++;
    case 3:
        y++;
    case 4:
        y++;
}
System.out.println("y="+y);

2.3 for

语法

for(初始化表达式;条件表达式;循环后的操作表达式) {
		循环体;
}

/*

		a:执行初始化语句
		b:执行判断条件语句,看其返回值是true还是false
  			如果是true,就继续执行
  			如果是false,就结束循环
	    c:执行循环体语句;
		d:执行循环后的操作表达式
		e:回到b继续
*/

例如,常见的几种写法

//for循环的常用写法
for(int i=0;i<10;i++){
    System.out.println("hello world");
}

//初始化变量和改变变量的值,是可以写到其他地方的
//这个最后的效果和上面的for循环是一样的
int i = 0;
for(;i<10;){
    System.out.println("hello world");
    i++;
}

//这是一个死循环代码,for的小括号中,只有俩个分号
for(;;){
    System.out.println("hello world");
}

//for循环的大括号中,如果只有一句代码,那么可以把大括号省去不写
for(;;) System.out.println("hello world");

例如,使用for循环完成从1累加到100

int sum = 0;
for (int i = 1; i <= 100; i++) {
    sum = sum + i;//sum+=i;
}
System.out.println(sum);

如何使用for循环实现累加1~100之间的奇数?

2.4 while

例如,循环不断的生成[0,9]随机数,直到生成随机数为5的时候,那么就停止这个循环。

int num = -1;
while(num!=5){
    num = (int)(Math.random()*10);
    System.out.println("num = "+num);
}

注意,Math是java.lang包的,可以直接使用,而不需要import导入

Math.random()方法会返回[0,1)之间的随机数,返回值类型是double

例如,使用for循环完成上述功能

int num = -1;
for(;num!=5;){
    num = (int)(Math.random()*10);
    System.out.println("num = "+num);
}

2.5 do-while

do-while循环和while循环很类似,只是do-while循环需要先执行循环体中的代码,然后再进行条件判断,是否可以进行一下次循环。特点,无论如何都会先执行一次大括号中的代码

例如,循环不断的生成[0,9]随机数,直到生成随机数为5的时候,那么就停止这个循环。

int a;
do{
    a = (int)(Math.random()*10);
    System.out.println("a = "+a);
}while(a!=5);

2.6 循环嵌套

在一个循环中,可以嵌套另一个循环。

例如,输出5个空行

for(int i=0;i<5;i++){
    System.out.println();
}

例如,在同一行,输出10个五角星

for(int i=0;i<10;i++){
    System.out.print("☆");
}

例如,输出5行,每行10个五角星

for(int i=0;i<5;i++){
    for(int j=0;j<10;j++){
        System.out.print("☆");
    }
    System.out.println();
}

println方法最后会自动换行
print 方法最后不会自动换行

例如,输出以下内容:
image-20200723013124231

for(int i=0;i<5;i++){
    for(int j=0;j<i+1;j++){
        System.out.print("*");
    }
    System.out.println();
}

例如,输出以下内容:
image-20200723013215349

//参数line表示要输出的行数
public void test(int line){
    //外层循环控制打印的行数
    for(int i=1;i<=line;i++){
        //这个循环控制每行打印的空格
        for(int j=0;j<line-i;j++){
            System.out.print(" ");
        }
        //这个循环控制每行打印的*
        for(int k=0;k<(2*i-1);k++){
            System.out.print("*");
        }
        //当前行中的空格和*都打印完了,最后输出一个换行
        System.out.println();
    }

}

例如,输出以下内容:
image-20200723013354177

//参数line表示要输出的行数
public void test(int line){
    //外层循环控制打印的行数
    for(int i=1;i<=line;i++){
        //这个循环控制每行打印的空格
        for(int j=0;j<(i-1);j++){
            System.out.print(" ");
        }
        //这个循环控制每行打印的*
        for(int k=0;k<(2*line-2*i+1);k++){
            System.out.print("*");
        }
        //当前行中的空格和*都打印完了,最后输出一个换行
        System.out.println();
    }

}

3 break

break 的意思是退出,结束当前的循环或switch代码。

例如,for循环从0到10进行输出,当i的值为5时,跳出当前循环(循环整体结束)

for(int i=0;i<10;i++){
    System.out.println("i = "+i);
    if(i==5){
        break;
    }
}

4 continue

continue 的意思是结束本次循环,让循环直接进入一次的运行。

例如,for循环从0到10进行输出,当i的值为5时,结束本次循环,进入一下次循环

for(int i=0;i<10;i++){
   
    if(i==5){
        continue;
    }
    System.out.println("i = "+i);
    
}

5 label

例如,在嵌套循环中使用 break 或 continue 关键字

for(int i=0;i<3;i++){//外层循环
    for(int j=0;j<5;j++){//内层循环
        if(j==2){
            break;
        }
    }
}

注意,默认情况下,在嵌套循环中,break和continue只能默认对当前循环其作用。

如果想让break或continue针对某一个指定的循环起作用,那么可以使用label标签给循环起名字,然后使用break或continue加上循环的名字即可。

例如,

test1:for(int i=0;i<3;i++){//外层循环
    test2:for(int j=0;j<5;j++){//内层循环
        if(j==2){
            break test1;
        }
        System.out.println("i="+i+",j="+j);
    }
    System.out.println("----------------------");
}

如果要跳出多层循环

label;(跳出指定循环)

return;(方法结束)

作业:
写LoopTest.java,
分别使用while/do/for循环实现1x2x…x10。

public class Test {
public static void main (String[] args){
    int sum1=1;
    for(int i = 1;i<=10;i++){
        sum1*=i;
    }
    System.out.println(sum1);
    int sum2=1;
    int i = 1;
    while(i<=10){
        sum2*=i;
        i++;
    }
    System.out.println(sum2);
    int sum3=1;
    int j = 1;
    do{
        sum3*=j;
        j++;
    }while(j<=10);
    System.out.println(sum3);
}
}

创建一个阶乘应用程序Factor.java
功能:一个数X 的阶乘(通常记作X!)等于X*(X-1)(X-2)…*1。例如4!等于4×3×2×1=24。

public class Factor{
    public static void main(String[] args) {
        int sum = 1;
        for(int i = 5;i>0;i--){
            sum*=i;
        }
        for(int j = 5;j>0;j--){
            if(j==5){
                System.out.print(j+"!: "+j);
            }else{
                System.out.print("*"+j);
            } 
        }
        System.out.print("="+sum);
    }
}

打印出四种形式的九九乘法表
提示:
1、System.out.println()的功能为输出+换行
System.out.print()的功能为输出
2、在适当的位置可以使用’\t’进行对齐操作

形式1:
11= 1
1
2= 2 22= 4
1
3= 3 23= 6 33= 9
14= 4 24= 8 34=12 44=16
15= 5 25=10 35=15 45=20 55=25
1
6= 6 26=12 36=18 46=24 56=30 66=36
1
7= 7 27=14 37=21 47=28 57=35 67=42 77=49
18= 8 28=16 38=24 48=32 58=40 68=48 78=56 88=64
19= 9 29=18 39=27 49=36 59=45 69=54 79=63 89=72 9*9=81

形式2:
19= 9 29=18 39=27 49=36 59=45 69=54 79=63 89=72 99=81
1
8= 8 28=16 38=24 48=32 58=40 68=48 78=56 88=64
1
7= 7 27=14 37=21 47=28 57=35 67=42 77=49
16= 6 26=12 36=18 46=24 56=30 66=36
15= 5 25=10 35=15 45=20 55=25
1
4= 4 24= 8 34=12 44=16
1
3= 3 23= 6 33= 9
12= 2 22= 4
1*1= 1

形式3:
11= 1
1
2= 2 22= 4
1
3= 3 23= 6 33= 9
14= 4 24= 8 34=12 44=16
15= 5 25=10 35=15 45=20 55=25
1
6= 6 26=12 36=18 46=24 56=30 66=36
1
7= 7 27=14 37=21 47=28 57=35 67=42 77=49
18= 8 28=16 38=24 48=32 58=40 68=48 78=56 88=64
19= 9 29=18 39=27 49=36 59=45 69=54 79=63 89=72 9*9=81

形式4:
19= 9 29=18 39=27 49=36 59=45 69=54 79=63 89=72 99=81
1
8= 8 28=16 38=24 48=32 58=40 68=48 78=56 88=64
1
7= 7 27=14 37=21 47=28 57=35 67=42 77=49
16= 6 26=12 36=18 46=24 56=30 66=36
15= 5 25=10 35=15 45=20 55=25
1
4= 4 24= 8 34=12 44=16
1
3= 3 23= 6 33= 9
12= 2 22= 4
1*1= 1

public class Multiplication{
    public static void main (String[] args){
        for(int i=1;i<10;i++){
            for(int j=1;j<i+1;j++){
                System.out.print(j+"*"+i+"="+i*j+"\t");
            }
                System.out.println();
        }
        System.out.println();

        for(int i=9;i>0;i--){
            for(int j=1;j<=i;j++){
                System.out.print(j+"*"+i+"="+i*j+"\t");
            }
                System.out.println();
        }
        System.out.println();

        for(int i=1;i<10;i++){
            for(int k =i;9-k>0;k++){
                System.out.print("   ");
            }
            for(int j=1;j<i+1;j++){
                System.out.print(j+"*"+i+"="+i*j+" ");
            }
                System.out.println();
        }
        System.out.println();
        
        for(int i=9;i>0;i--){
            for(int k =i;9-k>0;k++){
                System.out.print("   ");
            }
            for(int j=1;j<=i;j++){
                System.out.print(j+"*"+i+"="+i*j+" ");
            }
                System.out.println();
        }
    }
}

1,题目:有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
程序分析:可填在百位、十位、个位的数字都是1、2、3、4。组成所有的排列后再去
      掉不满足条件的排列。
Digit.java

public class Digit{
    public static void main(String[] args){
        int sum=0;
        for(int i = 1;i<5;i++){
            for(int j = 1;j<5;j++){
                for(int k = 1;k<5;k++){
                    if(i!=j&&i!=k&&j!=k){
                        sum++;
                        System.out.print(" "+i+j+k);
                    }
                }
            }
        }
        System.out.println("\n"+"能组成"+sum+"个互不相同且无重复数字的三位数");
    }
}

2,判断101-200之间有多少个素数,并输出所有素数。
只能被1和它本身整除的自然数为素数(质数)
Prime.java

public class Prime{
    public static void main (String[] args){
        
        for(int i = 101;i <= 200;i++){
            boolean b=true;
            for(int j = 2;j<i;j++){
                if(i%j==0){
                    b=false;
                }
            }
            if(b==true){
                System.out.print(i+" ");
            }
        }
    }
}

3,打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位
数字立方和等于该数本身。例如:153是一个“水仙花数”,因为
153=1的三次方+5的三次方+3的三次方。
Flower.java

Math.pow(a,3);
aaa

public class Flower{
    public static void main (String[] args){
        for(int i = 100;i<1000;i++){
            String str = Integer.toString(i);
            int a = Integer.parseInt(String.valueOf(str.charAt(0)));
            int b = Integer.parseInt(String.valueOf(str.charAt(1)));
            int c = Integer.parseInt(String.valueOf(str.charAt(2)));
            if(i==(Math.pow(a,3)+Math.pow(b,3)+Math.pow(c,3))){
                System.out.print(i+" ");
            }

        }
    }
}

4,将一个正整数分解质因数。例如:输入90,打印出90=233*5。

对n进行分解质因数,应先找到一个最小的质数k,然后按下述步骤完成:
a)如果这个质数恰等于n,则说明分解质因数的过程已经结束,
打印出即可。
b) 如果n不等于i,i能被n整除,则应打印出i的值,
并用n除以i的商,作为新的正整数n,重复执行第一步。

提示:如果一个自然数能写成两个自然数的乘积,那么这两个自然数就叫作原来那个数的因数。

Divide.java

import java.util.Scanner;
public class Divide{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入一个整数");
        int a = scan.nextInt();
        boolean b =false;
        for(int i =2;i<a;i++){
            if(a%i==0){
               b = true;
            }
        }
        if(b==false){
            System.out.print(a+"=1*"+a);
        }else{
            int mun = a;
            System.out.print(a+"=");
            while(a!=1){
                for(int j = 2;j<=a;j++){
                    if(a%j==0&&a==mun){
                        System.out.print(j);
                        a=a/j;
                    }else if(a%j==0){
                        System.out.print("*"+j);
                        a=a/j;
                    }
                }
            }
        }
    }
}

5,求任意两个正整数的最大公约数和(GCD)和最小公倍数(LCM)
辗转相除法的算法为:首先将 m除以 n(m>n)得余数 r,再用余数 r 去除原来的除数,得新的余数,重复此过程直到余数为 0时停止,此时的除数就是m 和 n的最大公约数。
求 m和 n的最小公倍数: m和 n的积除以(m和 n 的最大公约数)。
GcdLcm.java

import java.util.Scanner;
public class GcdLcm{
    public static void main (String[] args){
        Scanner scan1 = new Scanner(System.in);
        Scanner scan2 = new Scanner(System.in);
        System.out.println("请输入第一个整数");
        int a = scan1.nextInt();
        System.out.println("请输入第二个整数");
        int b = scan2.nextInt();
        int max = 0;
        int min = 0;
        if(a<b){
            max = b;
            min = a;
        }else{
            max = a;
            min = b;
        }
        int sum = max*min;
        int num = 0;
        for(int i =max;i/min>0;){
            i = i%min;
            num = i;
        }
        System.out.println(max+"、"+min+"最大公约数:"+num);
        int k = sum/num;
        System.out.println(max+"、"+min+"最大公倍数:"+k);
    }
}

6,求1000以内的完全数
若一个自然数,恰好与除去它本身以外的一切因数的和相等,这种数叫做完全数。
例如,6=1+2+3
28=1+2+4+7+14
496=1+2+4+8+16+31+62+124
先计算所选取的整数a(a的取值1~1000)的因数,将各因数累加于m,若m等于a,则可确认a为完全数
28/1=28 28/2 =14 28/3不行 28/4=7
Perfect.java

public class Perfect{
    public static void main (String[] args){
        for(int i = 0;i<=1000;i++){
            int k = 0;
            int n = i;
            for(int j = 1;j<n;j++){
                if(n%j==0){
                    k+=j;
                }
            }
            if(i==k&&i>1){
                System.out.print(k+"=");
                for(int j = 1;j<k;j++){
                    if(k%j==0&&j==1){
                        System.out.print(j);
                    }else if(k%j==0){
                        System.out.print("+"+j);
                    }
                }
                System.out.println();
            }
        }
    }
}
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页