20210130Java基本语法
Java基本语法
编辑时间:2021/01/30
读完本节:大概花费80分钟,共7542词
1.获取用户输入
导包:import java.util.Scanner;
Scanner的实例化:Scanner scan = new Scanner(System.in);
调用Scanner类的相关方法来获取指定类型的变量:next();或nextXxx();
常用的数据类型的Scanner获取方法
方法名 用法 nextByte() Scans the next token of the input as a byte. nextInt() Scans the next token of the input as a int. nextFloat() Scans the next token of the input as a float. nextDouble() Scans the next token of the input as a double. next() Return the next token if it matches the soecified pattern. nextBoolean() Scans the next token of the input as a boolean. Java8官网API:https://docs.oracle.com/javase/8/docs/api/index.html
Java8中文API:https://www.matools.com/api/java8
对于char类型的获取,Scanner没有提供相应的方法,只能获取一个字符串。
在String类下有charAt(int index)方法,可以返回index的具体的char值。
获取输入的第一个字符:
Scanner scan = new Scanner(System.in); String string = scan.next(); char stringFirstChar = string.charAt(0);
需要根据相应的方法来输入指定类型的值。如果输入的数据类型与要求的数据类型不匹配时,会报异常:InputMismatchException
练习1:
/* 宠物医院归档就诊狗狗的基本信息:昵称、性别、年龄、体重、是否节育 */ import java.util.Scanner; public class ScannerTest {public static void main(String[] args){Scanner scanner = new Scanner(System.in);System.out.println("Enter dog name: ");String name = scanner.next();System.out.println(name);//通过charAt()获取String的首位字符System.out.println("Enter dog gender:(F / M) ");String gender = scanner.next();char genderChar = gender.charAt(0);System.out.println(genderChar);System.out.println("Enter dog age: ");int age = scanner.nextInt();System.out.println(age);System.out.println("Enter dog weight:(kg) ");double weight = scanner.nextDouble();System.out.println(weight);System.out.println("Enter dog birth control status:(true / false) ");boolean bcStatus = scanner.nextBoolean();System.out.println(bcStatus);// System.out.println("Enter dog birth control status:(y / n) "); // String bcStatus = scanner.next(); // if(bcStatus.equals("y")){// System.out.println("Dog may need surgery in the future."); // }else{// System.out.println("Bitch control had done before."); // }} }
2.程序的流程控制
1分支结构
if-else分支结构
条件表达式必须是布尔表达式(关系表达式或逻辑表达式)、布尔变量。
语句中只有一条执行语句是,一对{}可以省略,但建议保留。
if-else语句结构可以嵌套使用。
if-else语句结构为多选一是,最后的else是可选的,根据需要可以省略。
当多个条件是为互斥关系时,条件判断语句及执行之间的顺序无所谓,当多个条件时包含关系时,被包含的条件要写在前面,保证有被执行的机会。当多个条件间时交集关系,需要根据实际情况考虑先后顺序。
if-else的语句格式
1. if形式
if(条件表达式){
表达式1;
}
2. if-else形式
if(条件表达式1){
表达式1;
}else if(条件表达式2){
表达式2;
}
3. if-else…if形式
if(条件表达式1){
表达式1;
}else if(条件表达式2){
表达式2;
}else if(条件表达式3){
表达式3;
}else if(条件表达式…){
表达式…;
}else if(条件表达式n){
表达式n;
}
4. if-else…if-else形式
if(条件表达式1){
表达式1;
}else if(条件表达式2){
表达式2;
}else if(条件表达式3){
表达式3;
}else if(条件表达式…){
表达式…;
}else if(条件表达式n){
表达式n;
}else{
表达式n+1;
}
练习1:
/* 判断狗狗是否处于节育适龄期(if-else实现) 当狗的年龄在 0-0.6岁 狗太小了,还未发育完全 0.6-0.8岁 适合节育手术 0.8-2.0岁 适合在未发情期进行节育手术 2.0岁以上 狗太大了,做手术可能存在风险 */ import java.util.Scanner; public class IfTest {public static void main(String[] args){Scanner scanner = new Scanner(System.in);System.out.println("输入狗的年龄:(例:0.5岁)");double age = scanner.nextDouble();if(age <= 0){System.out.println("狗子还没出生。");}else if(age > 0 && age <= 0.6){System.out.println("狗子太小了,还没结束发育。");}else if(age > 0.6 && age <=0.8){System.out.println("狗子处于节育适龄期,建议手术。");}else if(age > 0.8 && age <=2.0){System.out.println("若在狗子处于非发情期,建议手术。");}else{System.out.println("狗太大了,做手术可能存在风险。");}} }
练习2:
/* 编写程序: 1. 由键盘输入三个整数分别存入三个变量num1,num2,num3, 2. 对他们进行排序(if-else if-else)并从大到小输出。 */ import java.util.Scanner; public class VariableTest {public static void main(String[] args){Scanner scanner = new Scanner(System.in);System.out.println("Enter num1");int num1 = scanner.nextInt();System.out.println("Enter num2");int num2 = scanner.nextInt();System.out.println("Enter num3");int num3 = scanner.nextInt();if(num1 >= num2){if(num2 >= num3){System.out.println("num1 = " + num1 + ", num2 = " + num2 + ", num3 = " + num3);}else if(num3 >= num1){System.out.println("num3 = " + num3 + ", num1 = " + num1 + ", num2 = " + num2);}else{System.out.println("num1 = " + num1 + ", num3 = " + num3 + ", num2 = " + num2);}}else{if(num1 >= num3){System.out.println("num2 = " + num2 + ", num1 = " + num1 + ", num3 = " + num3);}else if(num3 >= num2){System.out.println("num3 = " + num3 + ", num2 = " + num2 + ", num1 = " + num1);}else{System.out.println("num2 = " + num2 + ", num3 = " + num3 + ", num1 = " + num1);}}} }
/* 对以下代码,若有输出指出输出结果 */ int x = 4, y = 1; if(x > 2){if(y > 2)System.out.println(x + y);System.out.println("1"); }elseSystem.out.println("x is " + x);//x is 4 /* 以上实例说明了if在只有一句内容时可以不加{},但是要注意书写格式。 因此建议在书写代码时,加上{},保证程序的可读性 同时,if-else应当保持两两对应、缩进的好习惯,避免阅读时出现逻辑错误。 if-else的配对是从内到外的,最内层的if配对它接下来最近的else */
//判断输出结果 boolean b = ture; if(b == false)System.out.println("a"); else if(b)System.out.println("b"); else if(!b)System.out.println("c"); elseSystem.out.println("d");//bboolean b = ture; if(b = false)System.out.println("a"); else if(b)System.out.println("b"); else if(!b)System.out.println("c"); elseSystem.out.println("d");//c
练习3:
/* 编写程序: 获取用户输入的狗的年龄 通过程序显示其相当于人类的年龄 如果用户输入负数,显示提示0-2岁,每一岁每一年相当于人类的10.5岁 >2岁,每增加一岁增加4岁 */ import java.util.Scanner; public class IfTest {public static void main(String[] args){Scanner scanner = new Scanner(System.in);//狗龄相当于人类多少岁System.out.println("输入狗的年龄:(例:2)");int dogAge = scanner.nextInt();if (dogAge >= 0 && dogAge <=2){System.out.println("相当于人类的年龄:" + dogAge * 10.5);}else if(dogAge > 2){System.out.println("相当于人类的年龄:" + (2 * 10.5 + (dogAge - 2) * 4));}else{System.out.println("狗子还没出生。");}} }
练习4:
/* 编写程序: 随机生成两位数 提示用户输入一个两位数 1)如果用户输入的数字与随机数 匹配 用户获得积分10000 2)如果用户输入的数字与随机数 匹配但是顺序不一致 用户获得积分3000 3)如果用户输入的数字与随机数 仅满足顺序情况下匹配一个数字 用户获得积分1000 4)如果用户输入的数字与随机数 仅满足非顺序情况下匹配一个数字 用户获得积分500 5)如果用户输入的数字与随机数 失配 用户获得积分0例:生成了一个随机数45 45 得10000分 54 得3000分 4* *5 得1000分 *4 5* 得500分 !45 得0分 */ import java.util.Scanner; public class IfTest {public static void main(String[] args){Scanner scanner = new Scanner(System.in);System.out.println("输入一个两位数:[10-99]");int token = scanner.nextInt();// //获取一个随机数 // double value1 = Math.random();//[0.0-1.0) // //获取[0.0-90.0)中的一个随机数 // double value2 = Math.random() * 90;//[0.0-90.0) // 生成随机数范围为[a,b]的公式: // (int)(Math.random() * (b - a + 1) + a);//获取[10-99]中的一个随机数int value = (int)((Math.random() * 90) + 10);//[10-99)//tens: 十位; digit: 个位int tensT = token / 10;int digitT = token % 10;int tensV = value / 10;int digitV = value % 10;if(tensT == tensV && digitT == digitV){System.out.println("随机数是:" + value);System.out.println("你输入的是:" + token + ",获得积分10000");}else if(digitT == tensV || tensT == digitV){System.out.println("随机数是:" + value);System.out.println("你输入的是:" + token + ",获得积分500");}else if(tensT == tensV || digitT == digitV){System.out.println("随机数是:" + value);System.out.println("你输入的是:" + token + ",获得积分3000");}else{System.out.println("随机数是:" + value);System.out.println("你输入的是:" + token + ",获得积分0");}} }
生成**随机数范围为[a,b]**的公式: (int)(Math.random() * (b - a + 1) + a);
switch-case分支结构
switch(表达式)中表达式的值必须是下述几种类型之一:byte,short,char,int,enmu(枚举,jdk5.0),String(字符串,jdk7.0)。
case子句中的值必须是常量,不能是变量命或不确定表达式的值。
同一个switch语句,所有case子句中的常量值互不相同。
break语句用来在执行完一个case分支后,使程序跳出switch语句块;如果没有break,程序会顺序执行到尾。
default子句是可任选的,相当于if-else结构中的else。同时,位置也是灵活的。当没有匹配的case时,执行default。
switch-case的语句格式
当写分支结构时,既可使用switch-case,又可使用if-else结构时,switch表达式取值情况少时优先选用(switch-case执行效率高)。
switch(表达式){
case 常量1:
语句1;
//break;
case 常量…:
语句…;
//break;
case 常量n:
语句n;
//break;
default:
语句;
//break;
}
练习1:
//判断输出结果String season = "summer"; switch (season){case "Spring":System.out.println("春");//break;case "summer":System.out.println("夏");break;case "autumn":System.out.println("秋");break;case "winter":System.out.println("冬");break;default:System.out.println("输入季节有误"); }/* 春 夏 */
练习2:
/* 使用switch吧小写类型的char转为大写。只转换:a, b, c, d, e。其他的输出other。 */ import java.util.Scanner; class SwitchCaseTest{public static void main(String[] args){Scanner scan = new Scanner(System.in);String word = scan.next();char letter = word.charAt(0);switch(letter){case a:System.out.println("A");break;case b:System.out.println("B");break;case c:System.out.println("C");break;case d:System.out.println("D");break;case e:System.out.println("E");break;}} }
练习3:
/* 对于学生成绩大于60分的,输出合格,低于60分的输出不合格。 */ import java.util.Scanner; class SwitchCaseTest{public static void main(String[] args){Scanner scan = new Scanner(System.in);int score = scan.nextInt();//方法一:switch(score/10){case 1:case 2:case 3:case 4:case 5:System.out.println("不合格");break;case 6:case 7:case 8:case 9:case 10:System.out.println("合格");break;default:System.out.println("成绩输入 有误");break;}//方法二:/*switch(score/60){case 0:System.out.println("不合格");break;case 1:System.out.println("合格");break;default:System.out.println("成绩输入 有误");break;}*/} }
练习4:
/* 根据输入的月份,打印所属季节(switch-case) 3 4 5春 6 7 8夏 9 10 11秋 12 1 2冬 */ import java.util.Scanner; public class SwitchCaseTest {public static void main(String[] args){Scanner scan = new Scanner(System.in);System.out.print("输入月份:");int month = scan.nextInt();//判断输入合法性if(month <= 0 || month > 12){System.out.println("输入月份 有误");}else{//switch case主体switch(month / 3){case 1:System.out.println("春季");break;case 2:System.out.println("夏季");break;case 3:System.out.println("秋季");break;case 0:case 4:System.out.println("冬季");break;}}} }
练习5:
/* 从键盘分别输入年月日,判断这一天是当年的多少天。 注:闰年:可以被4整除,但不被100整除 或 可以被400整除。 */ import java.util.Scanner; public class SwitchCaseTest {public static void main(String[] args){Scanner scan = new Scanner(System.in);//获取输入的年份String yearStr;System.out.print("输入 年份:");int year = scan.nextInt();//获取的年份数字若为 0125,最后自动读为 125//年份合法性检验boolean flag = false;if(year == 0){flag = true;}while (flag){System.out.print("输入正确的 年份:(不为0)");year = scan.nextInt();if(year == 0){flag = true;}else{flag = false;}}//yearStr赋值if(year < 0){yearStr = "公元前 " + (-year);}else{yearStr = "公元 " + (year);} // System.out.println(yearStr);// //将年份转化为字符串取首位的方法 // String yearStr = "" + year; // int y = Integer.parseInt("" + yearStr.charAt(0)); // System.out.println(y);//获取输入的月份System.out.print("输入 月份:");int month = scan.nextInt();//月份合法性检验while (month <= 0 || month > 12){System.out.print("输入正确的 月份:[1,12]");month = scan.nextInt();}//获取输入的日期System.out.print("输入 日期:");int date = scan.nextInt();//日期合法性检验if(year < 0){//公元前,没有公元0年,公元1年称为公元元年,所以若为公元前221年应当是闰年year = year + 1;//不复用的原因是便于阅读的连续性if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){//年份判断:闰年if(month == 1 || month ==3 || month ==5 || month ==7 || month ==8 || month ==10 || month ==12){//date==31while (date <= 0 || date > 31){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~31])");date = scan.nextInt();}}else if(month != 2){//date==30while (date <= 0 || date > 30){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~30])");date = scan.nextInt();}}else{//date=29while (date <= 0 || date > 29){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~29])");date = scan.nextInt();}}}else{//年份判断:平年if(month == 1 || month ==3 || month ==5 || month ==7 || month ==8 || month ==10 || month ==12){//date==31while (date <= 0 || date > 31){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~31])");date = scan.nextInt();}}else if(month != 2){//date==30while (date <= 0 || date > 30){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~30])");date = scan.nextInt();}}else{//date=28while (date <= 0 || date > 28){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~28])");date = scan.nextInt();}}}year--;}else if(year > 0){if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){//年份判断:闰年if(month == 1 || month ==3 || month ==5 || month ==7 || month ==8 || month ==10 || month ==12){//date==31while (date <= 0 || date > 31){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~31])");date = scan.nextInt();}}else if(month != 2){//date==30while (date <= 0 || date > 30){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~30])");date = scan.nextInt();}}else{//date=29while (date <= 0 || date > 29){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~29])");date = scan.nextInt();}}}else{//年份判断:平年if(month == 1 || month ==3 || month ==5 || month ==7 || month ==8 || month ==10 || month ==12){//date==31while (date <= 0 || date > 31){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~31])");date = scan.nextInt();}}else if(month != 2){//date==30while (date <= 0 || date > 30){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~30])");date = scan.nextInt();}}else{//date=28while (date <= 0 || date > 28){System.out.print("输入正确的 日期:(" + month + "月份日期范围是[1~28])");date = scan.nextInt();}}}}//输出计算这天是该年的第几天int sumDays = 0;switch(month){case 12:sumDays += 30;//这里加的30是11月的case 11:sumDays += 31;//这里加的31是10月的case 10:sumDays += 30;//同上,下同case 9:sumDays += 31;case 8:sumDays += 30;case 7:sumDays += 30;case 6:sumDays += 31;case 5:sumDays += 30;case 4:sumDays += 31;case 3:if(year < 0){//公元前,没有公元0年,公元1年称为公元元年,所以若为公元前221年应当是闰年year = year + 1;if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){//判断闰年sumDays += 29;}else{sumDays += 28;}year--;//恢复对数据的处理}else if(year > 0){if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){//判断闰年sumDays += 29;}else{sumDays += 28;}}case 2:sumDays += 31;case 1:sumDays += date;}//输出结果System.out.println(yearStr + " 年 " + month + " 月 " + date + " 日 是当年的第 " + sumDays + " 天。");if(year < 0){//公元前,没有公元0年,公元1年称为公元元年,所以若为公元前221年应当是闰年year = year + 1;if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){//判断闰年System.out.println(yearStr + " 是闰年。");}else{System.out.println(yearStr + " 是平年。");}year--;//恢复对输入数据year的处理}else if(year > 0){if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0){//判断闰年System.out.println(yearStr + " 是闰年。");}else{System.out.println(yearStr + " 是平年。");}}} }
练习6:
import java.util.Scanner; public class SwitchCase1 {public static void main(String[] args){Scanner scan = new Scanner(System.in);//获取用户输入的年分System.out.print("输入 年份:");int year = scan.nextInt();//年份合法性检验boolean flag = false;if(year == 0){flag = true;}while (flag){System.out.print("输入正确的 年份:(不为0)");year = scan.nextInt();if(year == 0){flag = true;}else{flag = false;}}//2021:牛年//2021 % 12 = 5; 2020 % 12 = 4; 2019 % 12 = 3; 2018 % 12 = 2;//2017 % 12 = 1; 2016 % 12 = 0; ...; 1 % 12 = 1//0monkey 1rooster 2dog 3pig 4rat 5ox 6tiger 7rabbit 8dragon 9snake 10horse 11sheep//0monkey -1sheep -2horse -3snake -4dragon -5rabbit -6tiger -7ox -8rat -9pig -10dog -11rooster//负数是倒着来的//theChineseZodiac 生肖String theChineseZodiac;switch(year % 12){case 7:case -5:theChineseZodiac = "rabbit";break;case 8:case -4:theChineseZodiac = "dragon";break;case 9:case -3:theChineseZodiac = "snake";break;case 10:case -2:theChineseZodiac = "horse";break;case 11:case -1:theChineseZodiac = "sheep";break;case 0://不存在公元0年theChineseZodiac = "monkey";break;case 1:case -11:theChineseZodiac = "rooster";break;case 2:case -10:theChineseZodiac = "dog";break;case 3:case -9:theChineseZodiac = "pig";break;case 4:case -8:theChineseZodiac = "rat";break;case 5:case -7:theChineseZodiac = "ox";break;case 6:case -6:theChineseZodiac = "tiger";break;default:theChineseZodiac = "null";break;}String yearStr;if(year < 0){yearStr = "公元前 " + year;}else{yearStr = "公元 " + year;}System.out.println(yearStr + " 是" + theChineseZodiac + "年");} }
1循环结构
循环结构的四个要素:①初始化部分(initial_statement);②循环条件部分(text_experiment)(布尔类型);③循环体部分(body_statement);④迭代部分(alter_statement);
for循环结构
for(①;②;④){//圆括号内的条件①、②或④若不止一句,使用逗号隔开
③;
}
执行过程:①→②→③→④→②→③→④→…→②→③→④→②
练习1:
//判断输出结果 int num = 1;for(System.out.print('a');num <= 3;System.out.print('c'),num++);System.out.print('b');}//abcbcbc
练习2:
/* 遍历100以内的所有偶数,输出所有偶数和、个数和 */ class ForTest{public static void main(String[] args){int sum = 0;//记录所有偶数和int count = 0;//记录偶数的个数for(int i = 0; i <= 100; i++){if(i % 2 == 0){System.out.println(i);sum += i;}}System.out.println("总和为:" + sum);System.out.println("个数为:" + count);} }
练习3:
/* 编写程序:1.从1循环到150,并在每一行打印一个值2.每个3的倍数行上打印出 aaa,5的倍数行上打印 bbb,7的倍数行上打印ccc */ public class ForTest {public static void main(String[] args){for (int i = 1; i <= 150; i++){System.out.print(i + " ");if(i % 3 == 0){System.out.print("aaa ");}if(i % 5 == 0){System.out.print("bbb ");}if(i % 7 == 0){System.out.print("ccc ");}//控制换行System.out.println();}} }
练习4:
/*打印所有的水仙花数(Narcissistic number)三位自幂数水仙花数:一个 3 位数,它的每个位上的数字的 3次幂之和等于它本身例如:1^3 + 5^3+ 3^3 = 153 */ public class ForTest {public static void main(String[] args){//print all Narcissistic number水仙花数for(int narcissisticNum = 100; narcissisticNum <= 999; narcissisticNum++){//求出各个位次的值int hundreds = narcissisticNum / 100;int tens = (narcissisticNum / 10) % 10;int digit = narcissisticNum % 10;//求各个位次的三次幂double hundredsP = Math.pow(hundreds,3);double tensP = Math.pow(tens,3);double digitP = Math.pow(digit,3);if(hundredsP + tensP + digitP == narcissisticNum){System.out.println(narcissisticNum);}}} }
while循环结构
①
while(②){
③;
④;//少了迭代部分会导致死循环的出现
}
执行过程:①→②→③→④→②→③→④→…→②→③→④→②
for循环和while循环的初始化条件的作用范围不同,for循环①处声明的初始化条件仅仅只能用在for循环体内部,出了for循环体则变量不合法
练习1:遍历100以内的所有偶数(while)
//遍历100以内的偶数(偶数能被2整除)。 class WhileTest{public static void main(String[] args){int i = 1; //初始化条件while(i <= 100){ //循环条件部分if(i % 2 == 0){ //循环体部分System.out.println(i);}i++; //循环迭代部分}//证明whlie初始化条件出了循环仍然可用System.out.println(i); //101} }
do-while循环结构
①
do{
③;
④;
}while(②);执行过程:①→③→④→②→③→④→…→②→③→④
do-while至少执行一次循环体。
练习1:遍历100以内的偶数,并计算所有偶数的和以及偶数的个数(do-while)
class DoWhileTest{public static void main(String[] args){int num = 1;int count = 0;//计数int sum = 0;//总和do{if(num % 2 == 0){System,out.println(num);sum += sum;count++;}num++;//控制条件的迭代}while(num <= 100);} }
练习2:写出打印结果
class WhlieDoWhlieTest{public static void main(String[] args){int number1 = 10;while(number1 > 10){number1--;//控制条件的迭代}int number2 = 10;do{System.out.println("do-whlie");number2--;//控制条件的迭代}whlie(number2 > 10);} } //do-while //上例很清晰的表明了就算do-while的条件不满足,也会执行循环体一次
练习3:循环语句综合例题
/* 从键盘读入不确定的整数,并判断读入的正数和负数的个数,输入0时结束程序常用的两种“无限”循环格式:while(ture)、for(;;),无线循环存在的原因是不知道循环几次, 需要根据循环体内部的条件来控制循环结束。 */ import java.util.Scanner; class LoopTest{public static void main(String[] args){Scanner scan = new Scanner(System.in);int postiveNumber = 0;int negtiveNumber = 0;System.out.println("输入整数继续,输入 0 停止:");while(true){//或for(;;){//获取输入int number = scan.nextInt();//判断正负if(number > 0){postiveNumber++;}else if(number < 0){negtiveNumber++;}else{break;//用于控制循环的结束。当上述两种情况不成立时,跳出。}}System.out.println("正数个数为:" + postiveNumber);System.out.println("负数个数为:" + negtiveNumber);} } /* 在循环条件部分限次无限时的控制结束语句有两种方式方式1:循环条件部分返回false;方式2:在循环体中执行break; */
嵌套循环
for_for嵌套
for(①;②;⑦){
for(③;④;⑥){
⑤
}
}
执行过程:①→②→③→④→⑤→⑥→…→④→⑤→⑥→④→⑦→②→③→④→⑤→⑥→…→④→⑤→⑥→④→⑦→②
③→④→⑤→⑥→…→④→⑤→⑥→④是内层循环,内层循环每执行一次,只相当于外层循环体执行了一次。若外层循环需要执行m次,内层循环需要执行n次。则内层循环体一共执行了m * n次。时间复杂度为o(m * n)
练习1:按要求打印
/* 打印以下图形: ***** ***** ***** ***** */ class ForForTest{public static void main(String[] args){//通常情况下,外层循环用于控制行数,内层循环用于控制列数for(int i = 1;i <=4;i++){//控制行for(int j = 1;j <= 5;j++){//控制列System.out.print("*");}System.out.println();}} }
/* 打印以下图形: * ** *** **** */ class ForForTest1{public static void main(String[] args){for(int i = 1;i <=4;i++){//控制行for(int j = 1;j <= i;j++){//控制列System.out.print("*");}System.out.println();}} }
/* 打印以下图形: i(行号) j(*的个数) *** 1 3 ** 2 2 * 3 1规律:i + j = 4 ==等价于== j = 4 - i */ class ForForTest2{public static void main(String[] args){//通常情况下,外层循环用于控制行数,内层循环用于控制列数for(int i = 1;i <=4;i++){//控制行for(int j = 1;j = 4 - i;j++){//控制列System.out.print("*");}System.out.println();}} }
练习2:九九乘法表
/* 1 * 1 = 1 2 * 1 = 2 2 * 2 = 4 ....... 9 * 1 = 9 .... 9 * 2 = 81 */ class NineNineTable{public static void main(String[] args){for(int i = 1;i <= 9;i++){for(int j = 1;j <= i;j++){System.out.print(i +" * " + j + " = " + i * j);}System.out.println();}} }
练习3:输出100以内的质数
public class PrimeNumberTest {public static void main(String[] args){//输出100以内的质数//质数:即素数,只能被1和它本身整除的自然数。//换言之质数是:在2到这个数减一的循环结束为止都不能被这个数本身整除//方法一:boolean flag = true;//用于标识i是否被j除尽,一旦i能被除尽则改为falsefor(int i = 2;i <= 100;i++){//遍历100以内的数for(int j = 2;j < i;j++){//除数从2-100遍历if(i % j == 0){//如果i能被j除尽flag = false;//将标识设为false}}if(flag){//在j结束遍历之后判断标识是否为true,若为真则打印System.out.println(i);}//在结束本次循环前恢复flag为真值以便下一次判断起始时仍为true/*也可以在进入循环之后再声明flag变量但是这样子做会导致每次进新循环会重新申请变量使程序运行时占用的内存空间大*/flag = true;}} }
public class PrimeNumberTest {public static void main(String[] args){//方法二://优化运行速度// 对于一个整数,在if判断中一旦有一个数能够将其除尽无需继续继续进行j后续数字的遍历// 因为已经可以确定的是这个数已经不是素数,所以在if程序块内添加break即可结束j的后续循环boolean flag = true;//用于标识i是否被j除尽,一旦i能被除尽则改为falsefor(int i = 2;i <= 100;i++){//遍历100以内的数for(int j = 2;j < i;j++){//除数从2-100遍历if(i % j == 0){//如果i能被j除尽flag = false;//将标识设为falsebreak;//只对本身非质数的自然数是有效的}}if(flag){//在j结束遍历之后判断标识是否为true,若为真则打印System.out.println(i);}//重置flagflag = true;}} }
//获取当前时间距离1970-01-01 00:00:00 的毫秒数 long start = System.currentTimeMillis(); //获取当前时间距离1970-01-01 00:00:00 的毫秒数 long end = System.currentTimeMillis(); System.out.println("所花费时间为:" + (end - start));
用上述的方法可以获取程序执行时间。
对于大规模(100000以内)的执行默认的方法一的程序执行时间(ms)为:
对于方法二在if中减少对非质数的后续数字的除尽判断能有效提升程序运行效率:
上述的大规模质数查找还能进一步优化时间
首先大于2的偶数一定不是质素,可以减少时间,但从时间复杂度的角度来说,意义不大o(n)于o(n / 2)本质上还是属于同一个量级的
对于循环的时间优化可以从一下几点入手:1)改善循环条件,减少循环次数 2)改善循环体内容
因此想要进一步优化可以在方法二的基础上对j的范围进行开方处理,属于改善循环条件
两个一个数可以分为两个数相乘,其中只有在开方的时候两个因数是相等的,因此只需要考虑2~sqrt(i)即可。
public class PrimeNumberTest {public static void main(String[] args){//方法三://优化运行速度// 对于一个整数,总是可以分为两个因数相乘,其中当两个因子相同时可以视作这个数开平方// 一个数只要是非质数,则一定可以分为两个因数,因此只要判断小的那个因子能否除尽即可boolean flag = true;//用于标识i是否被j除尽,一旦i能被除尽则改为falsefor(int i = 2;i <= 100000;i++){//遍历100以内的数for(int j = 2;j <= Math.sqrt(i);j++){//除数从2-sqrt(i)遍历if(i % j == 0){//如果i能被j除尽flag = false;//将标识设为falsebreak;//只对本身非质数的自然数是有效的}}if(flag){//在j结束遍历之后判断标识是否为true,若为真则打印System.out.println(i);}//在结束本次循环前恢复flag为真值以便下一次判断起始时仍为true/*也可以在进入循环之后再声明flag变量但是这样子做会导致每次进新循环会重新申请变量使程序运行时占用的内存空间大*/flag = true;}//获取当前时间距离1970-01-01 00:00:00 的毫秒数long end = System.currentTimeMillis();System.out.println("所花费时间为:" + (end - start));//改为输出100000个数内的质数方法三耗时1954ms} }
方法三的再次优化可以将输出质数的时间再次缩短:
break,continue关键字的使用
关键字 使用范围 循环中使用的作用(不同点) 相同点 break switch-case循环结构中 结束当前循环 同一个语句块中关键字后面不能声明执行语句 continue 循环结构中 结束当次循环 同一个语句块中关键字后面不能声明执行语句 练习:打印结果是?
class BreakContinueTest{public static void main(String[] args){for(int i = 1;i <= 10;i++){if(i % 4 == 0){break;}System.out.print(i);}} }//123
class BreakContinueTest{public static void main(String[] args){for(int i = 1;i <= 10;i++){if(i % 4 == 0){continue;}System.out.print(i);}} }//123567910
break和continue都是默认跳出最近的一层循环,若要跳出指定循环可以用“label:”在指定的循环结构起始位置标明,并且在终止语句后表明label。
就算加了label也不会改变关键字本身的作用,只是更改了关键字断开循环的位置,是结束当前循环还是结束当次循环取决于使用的关键字是break还是continue。
例:
class BreakContinueTest{public static void main(String[] args){label:for(int i = 1;i <= 4;i++){for(int j = 1;j <= 10;j++){if(i % 4 == 0){break label;//continue label;}System.out.print(j);}System.out.println();}} }/* 使用break label; 123使用continue label; 123123123123 */
对于return,return并非专门用于结束循环,它的功能是结束一个方法。当一个方法执行到return语句时,这个方法将被结束。与break和continue不同的是,return直接结束整个方法,不管这个return处于多少层循环之中。
针对寻找质数问题因此使用中断特殊循环的方式可以再进一步加快
public class PrimeNumberTest {public static void main(String[] args){//输出100以内的质数//质数:即素数,只能被1和它本身整除的自然数。//换言之质数是:在2到这个数减一的循环结束为止都不能被这个数本身整除//获取当前时间距离1970-01-01 00:00:00 的毫秒数long start = System.currentTimeMillis();//方法四:使用continue label的方式加速质数的寻找,不使用flag标志直接进行continue;操作label:for(int i = 2;i <= 100000;i++){//遍历100以内的数for(int j = 2;j <= Math.sqrt(i);j++){//除数从2-sqrt(i)遍历if(i % j == 0){//如果i能被j除尽continue label;//只对本身非质数的自然数是有效的}}System.out.println(i);}//获取当前时间距离1970-01-01 00:00:00 的毫秒数long end = System.currentTimeMillis();System.out.println("所花费时间为:" + (end - start));//改为输出100000个数内的质数方法四耗时63ms} }
方法四的执行结果为63ms。
减少时间不明显的原因在于调用输出语句会占用内存空间,导致整个程序运行速度降低,若本例为输出1~100000素数的个数,则能充分体现效果
public class PrimeNumberTest {public static void main(String[] args){//输出100以内的质数//质数:即素数,只能被1和它本身整除的自然数。//换言之质数是:在2到这个数减一的循环结束为止都不能被这个数本身整除//获取当前时间距离1970-01-01 00:00:00 的毫秒数long start = System.currentTimeMillis();//方法四(输出素数个数):使用continue label的方式加速质数的寻找,不使用flag标志直接进行break;操作int count = 0;label:for(int i = 2;i <= 100000;i++){//遍历100以内的数for(int j = 2;j <= Math.sqrt(i);j++){//除数从2-sqrt(i)遍历if(i % j == 0){//如果i能被j除尽continue label;//只对本身非质数的自然数是有效的}}count++;}//获取当前时间距离1970-01-01 00:00:00 的毫秒数long end = System.currentTimeMillis();System.out.println("质数的个数为:" + count);System.out.println("所花费时间为:" + (end - start));//改为输出100000个数内的质数方法四耗时14ms} }
20210130Java基本语法相关推荐
- 【JavaScript总结】JavaScript语法基础:BOM
DOM是文档对象模型,操作对象是文档 window.document,和浏览器没有直接关系 DOM常用事件: onload,onbeforeunload, onunload onclick,ondbl ...
- 【JavaScript总结】JavaScript语法基础:JS编码
运算符 数学:+. -. *. / 逻辑:>. < .>= .<=. == . !=.&&.|| . === .!==(完全等于) 对象相关 new delet ...
- 【JavaScript总结】JavaScript语法基础:数据类型
------>数据类型有哪些? ->基本类型:数字类型,布尔类型,字符串类型 ->引用类型:对象类型,函数类型 ->空类型:null 和 undefined ->运算符: ...
- 第二天:Vue基础语法
1.计算属性的setter和getter 每个计算属性都有setter和getter 一般来说用到setter较少,都不希望数据被改动,所以只用getter时也有缩写 <!DOCTYPE htm ...
- LLVM语法语义指令特性
LLVM语法语义指令特性 High Level Structure Module Structure LLVM 程序由Module's组成,每个 's 是输入程序的一个翻译单元.每个模块由函数,全局变 ...
- LLVM一些编程语法语义特性
LLVM一些编程语法语义特性 High Level Structure Module Structure LLVM 程序由Module's组成,每个 's 是输入程序的一个翻译单元.每个模块由函数.全 ...
- LLVM一些语法规则
LLVM一些语法规则 LLVM文档 LLVM编译器基础架构支持广泛的项目,从工业强度编译器到专门的JIT应用程序,再到小型研究项目. 同样,文档分为几个针对不同受众的高级别分组: LLVM设计概述 几 ...
- 2021年大数据Hive(四):Hive查询语法
全网最详细的Hive文章系列,强烈建议收藏加关注! 后面更新文章都会列出历史文章目录,帮助大家回顾知识重点. 目录 系列历史文章 前言 hive查询语法 一.SELECT语句 1.语句结构 2.全表查 ...
- 2021年大数据常用语言Scala(十八):基础语法学习 Map对象
目录 Map对象 不可变Map 可变Map Map基本操作 Map对象 Map可以称之为映射.它是由键值对组成的集合.在scala中,Map也分为不可变Map和可变Map. 不可变Map 定义 语法 ...
最新文章
- Web API With AJAX: Handle Session in Web API
- GDCM:gdcm::PhotometricInterpretation的测试程序
- Azkaban-solo模式-安装
- Android学习之Activity
- 【Python-2.7】列表与元组
- 编写脚本常用的几种语句
- 敏捷:什么是用户故事(User Story)
- paip.提升用户体验---WEB程序页面的手机及平板浏览器兼容支持
- FS_FT_DFT_DFS_DTFT傅里叶
- Unity Shader 伽马校正详解
- Tomcat中temp文件夹出现项目副本问题的解决方法
- 面向对象基础9(继承与继承语法)
- 技术人员谈管理之帕累托法则(80/20法则)
- Android作业批改系统(后台管理+前台app)
- 中南大学杰出校友_杰出客户服务的10个要点。
- html边框设置为背景同色,css边框与背景
- 海思 hikey970 开发板简介
- Kafka推送数据方法
- 南京大学计算机信息安全专业,信息安全专业按实力划分为九类,看看你喜欢的院校属于哪一类...
- 浪潮8465m4安装linux,NF8465M4 – IPMI设置