从if到万年历:Java流程控制与方法。
选择结构
if选择结构
if单选结构
语法
1 | if(条件表达式) { |
如果表达式为true,就会执行大括号内的代码块,之后继续向后执行if外面的代码,如果为false,就直接执行后面的代码, 不进入大括号中。
1 | import java.util.Scanner; |
随堂练习
- 根据年龄判断是否已经成年,年龄大于等于18表示成年。
1 | import java.util.Scanner; |
- 判断一个数是否在5(包含)到10(包含)之间。
1 | import java.util.Scanner; |
if双选结构
语法
1 | if(条件表达式) { |
如果条件表达式为true,就执行代码块1,否则,就执行代码块2。之后,向后执行if…else 之外的代码。
1 | import java.util.Scanner; |
随堂练习
- 模拟用户登录操作(用户名和密码都用字符串),需要判断出登录成功和登录失败的情况。
注意:判断字符串是否相同,不能使用==,而是需要使用equals方法。
1 | import java.util.Scanner; |
- 判断一个数字是奇数还是偶数,并输出判断结果。
1 | import java.util.Scanner; |
if多选结构
语法
1 | if(条件表达式1) { |
判断条件表达式1,如果为true,就执行代码块1
否则,判断条件表达式2,如果为true,就执行代码块2
否则,判断条件表达式3,如果为true,就执行代码块3
……..
否则,执行代码块n
最后,向后继续执行if外面的代码
其中 else if 可以有多个
实际上if的语法非常简单,1个if、0-n个else if、0-1个else
判断一个学生的成绩,如果90(包含)
100(包含)为优秀,70(包含)90为良好,60(包含)~70为及格,60分以下输出不及格。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24import java.util.Scanner;
public class Demo7If {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 判断一个学生的成绩
System.out.println("请输入一个学生的成绩:");
double score = sc.nextDouble();
// 如果90(包含)~100(包含)为优秀,
if(score < 0 || score > 100) {
System.out.println("分数不合规");
}else if(score >= 90 && score <= 100) {
System.out.println("优秀");
}else if(score >= 70 && score < 90) {
// 70(包含)~90为良好,
System.out.println("良好");
}else if(score >= 60 && score < 70) {
// 60(包含)~70为及格,
System.out.println("及格");
}else {
// 60分以下输出不及格。
System.out.println("不及格");
}
}
}输入一个整数month代表月份,根据月份输出对应的季节。
春季:3、4、5 夏季:6、7、8 秋季:9、10、11 冬季:12、1、21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33import java.util.Scanner;
public class Demo8If {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个月份");
int month = sc.nextInt();
// 输入一个整数month代表月份,根据月份输出对应的季节。
// 春季:3、4、5 夏季:6、7、8 秋季:9、10、11 冬季:12、1、2
/*if(month < 1 || month > 12) {
System.out.println("您输入的月份不合法");
}else if(month >= 3 && month <= 5) {
System.out.println("春季");
}else if(month >= 6 && month <= 8) {
System.out.println("夏季");
}else if(month >= 9 && month <= 11) {
System.out.println("秋季");
}else {
System.out.println("冬季");
}
*/
if(month < 1 || month > 12) {
System.out.println("您输入的月份不合法");
}else if (month == 12 || month ==1 || month == 2) {
System.out.println("冬季");
}else if(month <= 5) {
System.out.println("春季");
}else if(month <= 8) {
System.out.println("夏季");
}else {
System.out.println("秋季");
}
}
}输入工作年限(year)和月薪(money),然后计算出应得的年终奖。
工作不满1年(不包含): 发月薪的1倍月薪年终奖;如果月薪大于8000, 那么就是发1.2倍月薪年终奖。
工作不满3年(不包含):发月薪的2倍月薪年终奖;如果月薪大于15000, 那么就是发3倍月薪年终奖。
工作满3年(包含)以上:发月薪的3倍月薪年终奖;如果月薪大于20000, 那么就是发4倍月薪年终奖。
1 | import java.util.Scanner; |
录入一个年份,判断其是否为闰年。
闰年的计算方法:年数能被4整除,并且不能被 100整除;或者能被400整除的整数年份。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18import java.util.Scanner;
public class Demo10If {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 录入一个年份,判断其是否为闰年。
System.out.println("请输入一个年份:");
int year = sc.nextInt();
// 闰年的计算方法:年数能被4整除,
if(year % 4 == 0 && year % 100 != 0) {
System.out.println(year + "是闰年");
}else if(year % 400 == 0) {
// 并且不能被 100整除;或者能被400整除的整数年份。
System.out.println(year + "是闰年");
}else {
System.out.println(year + "不是闰年");
}
}
}输入时(hour)、分(minute)、秒(second)的一个具体时间,要求打印出它的下一秒出来(一天24小时)。
- 导包、创建Scanner对象、录入时分秒
- 将秒+1
- 如果秒数为60,将分+1,秒归零
- 如果分为60,将时+1,分归零
- 如果时为24,将时归零
- 如果时是0-9,将时前面补一个0,分、秒同理
- 按照类似于 10:12:13 的形式输出时间
1 | import java.util.Scanner; |
if语句使用总结
- if语句总结为一个语法:
1个if,0-多个else if,0-1个else - 如果if的大括号中只有一条语句时,大括号可以省略,但是不建议省略
- 大括号中的内容也称之为代码块,在代码块中定义的常量或者变量只能在代码块中使用
- 能用多选结构就不要用单选结构,因为if多选结构的性能要比后者高
- 选择结构语句可以互相进行嵌套(还可以嵌套循环结构)
switch选择结构
1 | switch(表达式) { |
switch会匹配表达式的值,如果匹配到值1,就从值1处开始执行,直到遇到break语句或者是switch语句的末尾,如果所有的case都没有匹配,就从default开始执行,执行到break语句或者switch的末尾。
1 | import java.util.Scanner; |
总结
- switch语句中,所有的case和default没有顺序关系,匹配到了谁就从谁开始执行,执行到第一个break,因此default中的break也不要省略
- switch中的数据类型只能为byte、short、int、char、String、枚举,并且case的值必须与switch中的数据类型一致
- 可以根据switch的执行机制,巧妙地省略一些break,从而实现某些场景的定制化逻辑。
- 在switch中可以进行一些条件判断,当满足某些判断条件时,可以在这个情况下直接break,不走后面的代码
- switch中所有的case和default共用一个命名空间,即:所有的case和default中不能出现重名变量。解决方案:可以使用不同名变量,也可以使用大括号括起来,形成一个代码块
JDK12以后的版本,程序还能改写成这样
1 | import java.util.Scanner; |
随堂练习
输入一个整数,对应的显示出星期几, 例如: 输入“1”,输出为“星期一” 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34import java.util.Scanner;
public class Demo13Switch {
public static void main(String[] args) {
// 输入一个整数,对应的显示出星期几, 例如: 输入“1”,输出为“星期一” 。
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
switch(num) {
case 1:
System.out.println("星期一");
break;
case 2:
System.out.println("星期二");
break;
case 3:
System.out.println("星期三");
break;
case 4:
System.out.println("星期四");
break;
case 5:
System.out.println("星期五");
break;
case 6:
System.out.println("星期六");
break;
case 7:
System.out.println("星期日");
break;
default:
System.out.println("您输入的数字有误");
break;
}
}
}接收一个人的成绩, 如果成绩为: 90(包含)到100(包含)输出优秀, 70(包含)到90输出良好, 60(包含)到70输出及格, 60分以下输出不及格。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39import java.util.Scanner;
public class Demo14Switch {
public static void main(String[] args) {
// 接收一个人的成绩, 如果成绩为: 90(包含)到100(包含)输出优秀,
// 70(包含)到90输出良好, 60(包含)到70输出及格, 60分以下输出不及格。
Scanner sc = new Scanner(System.in);
double score = sc.nextDouble();
int intScore = (int) score;
int result = intScore / 10;
switch(result) {
case 10:
if(score > 100) {
System.out.println("分数不合法");
break;
}
case 9:
System.out.println("优秀");
break;
case 7:
case 8:
System.out.println("良好");
break;
case 6:
System.out.println("及格");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
System.out.println("不及格");
break;
default:
System.out.println("成绩有误");
break;
}
}
}查询水果的价格,根据输入水果(fruit)的名字,输出对应的水果的价格,例如苹果6块/斤,香蕉3元/斤,榴莲20元/斤,西瓜0.8元/斤。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26import java.util.Scanner;
public class Demo15Switch {
public static void main(String[] args) {
// 查询水果的价格,根据输入水果(fruit)的名字,输出对应的水果的价格,
// 例如苹果6块/斤,香蕉3元/斤,榴莲20元/斤,西瓜0.8元/斤。
Scanner sc= new Scanner(System.in);
String name = sc.next();
switch(name) {
case "苹果":
System.out.println("6块/斤");
break;
case "香蕉":
System.out.println("3块/斤");
break;
case "榴莲":
System.out.println("20块/斤");
break;
case "西瓜":
System.out.println("你劈我瓜是吧");
break;
default:
System.out.println("进货中....");
break;
}
}
}编写一个简单的加减乘除计算器,按顺序输入数字、运算符、数字,计算出运算结果。
- 三个变量:一个数字、一个符号、一个数字
- 输入这三个变量
- 使用switch判断运算符,根据指定的运算符运行特定的代码块
1 | import java.util.Scanner; |
if和switch的对比
switch一般应用于固定值的判断
if建议用于范围值的判断
switch能够实现的if都可以实现,但反之则不行
此外,如果固定值判断,需要判断的内容太多,也建议使用if
循环结构
循环结构的作用是让代码在满足某个条件的情况下不断重复的执行某一块代码,直到条件不满足为止。
for循环结构
语法
1 | for(初始化表达式; 循环条件表达式; 循环后表达式) { |
执行机制
- 执行一次初始化表达式
- 判断循环条件表达式是否为true
- 如果为true,执行代码块
- 执行一次循环后表达式
- 从2开始重复执行,直到循环条件表达式为false为止
1 | package forstudy; |
for循环编写之前要确定几件事情
- 从什么时候开始循环
- 什么时候循环结束
- 每次循环的步进是多少
如果不关注从几循环到几,只关注循环多少次,可以这么写
1 | for(int i = 0; i < 次数; i++) { |
idea中生成for循环有快捷键
正向循环:fori
逆向循环:n.forr
循环到n:n.fori
随堂练习
输出0(包含)到100(包含)之间的数, 分别以递增和递减的方式实现;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package forstudy;
/**
* 输出0(包含)到100(包含)之间的数, 分别以递增和递减的方式实现;
*/
public class Demo2For {
public static void main(String[] args) {
System.out.println("递增方式实现:");
for(int i = 0; i <= 100; i++) {
System.out.print(i + " ");
}
System.out.println();
System.out.println("递减方式实现");
for(int i = 100; i >= 0; i--) {
System.out.print(i+ " ");
}
}
}输出1到100之间的奇数和偶数;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27package forstudy;
/**
* 输出1到100之间的奇数和偶数;
* 如果一次循环不方便把所有的需求编写完毕
* 可以进行多次循环
*/
public class Demo3For {
public static void main(String[] args) {
// 从1开始循环到100,步进值:1
System.out.println("奇数:");
for(int i = 1; i<= 100;i++) {
// 如果这个数字是奇数,就按照奇数进行输出
if(i % 2 == 1) {
System.out.print(i+" ");
}
}
System.out.println();
System.out.println("偶数:");
for(int i = 1;i<=100;i++) {
if(i % 2 == 0) {
System.out.print(i+" ");
}
}
}
}输入一个正整数n,计算1+2+3+…+n的和;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package forstudy;
import java.util.Scanner;
/**
* 输入一个正整数n,计算1+2+3+…+n的和;
* 求和类问题:
* 在循环之外创建一个变量用来记录当前的和
* 在循环之内不停的将每次循环到的值加到这个变量上
*/
public class Demo4For {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个正整数:");
int n = sc.nextInt();
int sum = 0;
for(int i = 1; i <= n; i++) {
sum += i;
}
System.out.println("1 + 2 + ... + " + n + " = " + sum);
}
}输入一个正整数n,计算1-2+3-4+5-6+…-(n-1)+n的和;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package forstudy;
import java.util.Scanner;
/**
* 输入一个正整数n,计算1-2+3-4+5-6+…-(n-1)+n的和;
*/
public class Demo5For {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个正整数n:");
int n = sc.nextInt();
int sum = 0;
for(int i = 1; i <= n; i++) {
if(i % 2 == 0) {
sum -= i;
}else{
sum += i;
}
}
System.out.println(sum);
}
}输出1到1000之间既能被5整除又能被3整除的数,并且每行输出5个。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24package forstudy;
/**
* 5. 输出1到1000之间既能被5整除又能被3整除的数,并且每行输出5个。
* 计数器问题
* 在循环外创建一个计数器,每次循环中满足条件之后,将计数器+1
* 当计数器加到满足某个条件时,执行某段代码,将计数器归零重新计数
*/
public class Demo6For {
public static void main(String[] args) {
int count = 0;
for(int i = 1;i <= 1000;i++) {
if(i % 5 == 0 && i % 3 == 0) {
System.out.print(i + " ");
count++;
if(count == 5) {
System.out.println();
count = 0;
}
}
}
}
}求100到999之间的水仙花数。水仙花数的每个位上的数字的3次幂之和等于它本身(例如:1^3 + 5^3+ 3^3 = 153)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42package forstudy;
/**
* 6. 求100到999之间的水仙花数。
* 水仙花数的每个位上的数字的3次幂之和等于它本身
* (例如:1^3 + 5^3+ 3^3 = 153)。
*/
public class Demo7For {
/**
* 实现方案2
* 循环是可以嵌套的,即:循环内可以再写一个循环
* @param args
*/
public static void main(String[] args) {
for(int i = 1; i <= 9; i++) {
for(int j = 0; j <= 9; j++) {
for (int k = 0; k <= 9 ; k++) {
if(i*i*i+j*j*j+k*k*k == 100*i+10*j+k) {
System.out.println(""+i+j+k);
}
}
}
}
}
/**
* 实现方案1
* 从100循环到999,取出每一位按照公式进行计算
* @param args
*/
public static void main1(String[] args) {
for(int i = 100; i <= 999; i++) {
int n1 = i / 100;
int tmp = i % 100;
int n2 = tmp / 10;
int n3 = tmp % 10;
if(n1*n1*n1 + n2*n2*n2 + n3*n3*n3 == i) {
System.out.println(i);
}
}
}
}编程找出四位整数abcd中满足下述关系的数,(ab+cd)*(ab+cd)=abcd(例如:(20 + 25) * (20 + 25)= 2025)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package forstudy;
/**
* 编程找出四位整数abcd中满足下述关系的数
* (ab+cd)*(ab+cd)=abcd(例如:(20 + 25) * (20 + 25)= 2025)。
*/
public class Demo8For {
public static void main(String[] args) {
for(int i = 1000; i <= 9999; i++) {
int a = i / 100;
int b = i % 100;
if((a+b)*(a+b) == i) {
System.out.println(i);
}
}
}
}
while循环
语法
1 | while(条件表达式) { |
只要条件表达式为true,就一直执行代码块,直到条件表达式为false,或者遇到break为止。while一般用于循环次数不确定,或者想一直循环下去的场景
1 | package whilestudy; |
do…while循环
语法
1 | do { |
先执行代码块,再判断条件表达式,如果为true,继续执行,如果false,结束循环。
do-while适用于想要让循环体至少执行一次的场景。
1 | package dowhile; |
随堂练习
输入一个正整数,然后把该正整数转化为二进制。
1 | package whilestudy; |
break和continue
break
可以在switch语句中当中,用来结束switch的运行
可以使用在循环语句中,终止循环。
1 | package breakcontinue; |
如果break同时出现在switch和循环语句中,只对最近的那个有影响
1 | package breakcontinue; |
continue
用于循环语句中,用于终止某次循环过程,继续后续的循环
1 | package breakcontinue; |
break可以让while循环更加简单,让判断循环结束条件不用再while的括号中进行,而是在代码块中使用if语句来灵活的控制循环的结束
1 | package breakcontinue; |
带标签的break和continue
标签是指后面跟着一个冒号的标识符,比如 abcd:
1 | package breakcontinue; |
带标签的break和continue不建议使用,因为它破坏了程序的结构性,使得程序调试起来相当困难,上面的程序可以改写成下面的结果
1 | package breakcontinue; |
随堂练习
使用continue实现输出1到100之间能被5整除的数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package breakcontinue;
/**
* 使用continue实现输出1到100之间能被5整除的数。
*/
public class Demo7BreakContinue {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
if(i % 5 != 0) {
continue;
}
System.out.println(i);
}
}
}韩信点兵,三人一组余两人,五人一组余三人,七人一组余四人,请问最少需要多少士兵。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19package breakcontinue;
/**
* 韩信点兵,三人一组余两人,五人一组余三人,七人一组余四人,
* 请问最少需要多少士兵。
*/
public class Demo8BreakContinue {
public static void main(String[] args) {
int count = 7;
while (true) {
count++;
if(count % 3 == 0 && count % 5 == 0 && count%7 == 0) {
break;
}
}
System.out.println("最少需要" +count + "人");
}
}输入一个任意整数,判断它是否为质数,如果是质数就输出“是质数”,否则输出‘不是质数’。质数:除了1和它本身之外,不能被其他数整除的正整数称质数。
方案一:假设法正向思路不好实现时,可以使用逆向思维,即假设法。先假设这个数是质数,在循环中尝试证明它不是质数,在循环之外,如果证明成功,则说明不是质数,如果证明失败,则说明是质数。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29package breakcontinue;
import java.util.Scanner;
/**
* 输入一个任意整数,判断它是否为质数,
* 如果是质数就输出“是质数”,否则输出‘不是质数’。
* 质数:除了1和它本身之外,不能被其他数整除的正整数称质数。
*/
public class Demo9BreakContinue {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
// 假设是质数
boolean flag = true;
for (int i = 2; i < num; i++) {
if(num % i == 0) {
flag = false;
break;
}
}
if(flag) {
System.out.println("是质数");
}else {
System.out.println("不是质数");
}
}
}方案二:分析for循环的执行机制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23package breakcontinue;
import java.util.Scanner;
public class Demo10BreakContinue {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
int i = 2;
for (; i < num; i++) {
if(num % i == 0) {
break;
}
}
System.out.println(num + ":" + i);
if(i == num) {
System.out.println("是质数");
}else {
System.out.println("不是质数");
}
}
}实际开发建议使用第一种,假设法比较通用,可以解决很多场景的问题,并且假设法便于优化
三种循环结构对比
for循环一般应用于能够确定循环次数,或者能够确定从几循环到几的场景。
while循环一般应用于不确定循环次数,或者想让循环一直执行下去的场景,以及不确定循环结束条件的场景(结合break)
do-while循环一般应用于想让循环体至少执行一次的场景。
事实上三种循环互相之间可以进行替代,但是我们依然需要养成习惯,在合适的场景选择合适的解决方案。
嵌套循环
在循环可以再嵌套一个循环。
外层循环控制内循环执行多少轮,内层循环每一轮都正常从头到尾进行循环。
1 | package doublefor; |
随堂练习
在控制台先打印矩形,然后再打印平行四边形,再然后打印等腰三角形。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42package doublefor;
/**
* 1、在控制台先打印矩形,然后再打印平行四边形,再然后打印等腰三角形。
*
*
*
*
*/
public class Demo2For {
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 8; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println();
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5-1-i; j++) {
System.out.print(" ");
}
for (int j = 0; j < 8; j++) {
System.out.print("*");
}
System.out.println();
}
System.out.println();
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5-1-i; j++) {
System.out.print(" ");
}
for (int j = 0; j < 2*i+1; j++) {
System.out.print("*");
}
System.out.println();
}
}
}使用嵌套循环实现九九乘法表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16package doublefor;
/**
* 2、使用嵌套循环实现九九乘法表。
*/
public class Demo3For {
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 + "=" + (j*i) + "\t");
}
System.out.println();
}
}
}输入0-9之间的一个数,输出数字构成的1~5位整数的和,如输入2,则计算出2 + 22 + 222 + 2222 + 22222之和。
需要解决的问题:1.计算出每一次循环的数字num,2.将每次循环到的数字进行求和result
假设输入n = 2,num = n第一趟:result = result + num,num = num * 10 + n=> result = 2, num = 22
第二趟:result = result + num,num = num * 10 + n => result = 2 + 22, num = 222
第三趟:result = result + num,num = num * 10 + n => result = 2+ 22+222,num = 22221
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22package doublefor;
import java.util.Scanner;
/**
* 输入0-9之间的一个数,输出数字构成的1~5位整数的和,
* 如输入2,则计算出2 + 22 + 222 + 2222 + 22222之和。
*/
public class Demo4For {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int result = 0;
int num = n;
for (int i = 0; i < 5; i++) {
result += num;
num = num * 10 + n;
}
System.out.println(result);
}
}搬砖问题:36块砖,36个人搬,男搬4块,女搬3块,两个小孩搬1块,要求一次搬完,问需要男、女、小孩各多少人?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26package doublefor;
/**
* 搬砖问题:36块砖,36个人搬,男搬4块,女搬3块,两个小孩搬1块
* 要求一次搬完,问需要男、女、小孩各多少人?
* 三层循环
* 男人范围:[0, 9]
* 女人范围:[0, 12]
* 小孩范围:[0, 36]
*
*
*/
public class Demo5For {
public static void main(String[] args) {
for (int i = 0; i <= 9; i++) {
for (int j = 0; j <= 12; j++) {
for (int k = 0; k <= 36; k+=2) {
if(i+j+k==36 && i*4+j*3+k/2 == 36) {
System.out.println("男人:" + i + ",女人:" + j + ",小孩:" + k );
}
}
}
}
}
}假如有一对小兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,请问每个月的兔子总数为多少对?(假设到24个月)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31package doublefor;
/**
* 假如有一对小兔子,从出生后第3个月起每个月都生一对兔子,
* 小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,
* 请问每个月的兔子总数为多少对?(假设到24个月)
* 第1月 第2月 第3月 第4月 第5月 第6月
* 小兔子 1 1 1 2 3 5
* 老兔子 0 0 1 1 2 3
* 总兔子 1 1 2 3 5 8
* 总兔子 = 上个月+上上个月
* 第3月 第4月 第5月 第6月
* 本月 2 3 5 8
* 上月 1 2 3 5
* 上上月 1 1 2 3
*/
public class Demo6For {
public static void main(String[] args) {
int first = 1;
int second = 1;
System.out.println("第1个月兔子数:1");
System.out.println("第2个月兔子数:1");
for (int i = 3; i <= 24; i++) {
int result = first + second;
second = first;
first = result;
System.out.println("第"+i+"个月兔子数:"+result);
}
}
}中国古代数学家研究出了计算圆周率最简单的办法: PI=4/1-4/3+4/5-4/7+4/9-4/11+4/13-4/15+4/17…… 这个算式的结果会无限接近于圆周率的值,我国古代数学家祖冲之计算出,圆周率在3.1415926和3.1415927之间,请编程计算,要想得到这样的结果,他要经过多少次…
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34package doublefor;
/**
* 中国古代数学家研究出了计算圆周率最简单的办法:
* PI=4/1-4/3+4/5-4/7+4/9-4/11+4/13-4/15+4/17......
* 这个算式的结果会无限接近于圆周率的值,我国古代数学家祖冲之计算出,
* 圆周率在3.1415926和3.1415927之间,
* 请编程计算,要想得到这样的结果,他要经过多少次...
*
* count=0,分母=1
* count=1,分母=3
* count=2,分母=5
*
*
*/
public class Demo7For {
public static void main(String[] args) {
double PI = 0;
int count = 0;
while (true) {
if(count % 2 == 0) {
PI += 4.0 / (count*2+1);
}else {
PI -= 4.0 / (count*2+1);
}
count++;
if(PI >= 3.1415926 && PI <= 3.1415927) {
break;
}
}
System.out.println("总共计算了" + count+"次,PI=" + PI);
}
}
方法
什么是方法
方法就是在类中的具有特定功能的一段独立的小程序,用来完成某个特定的功能
语法
方法的声明
1 | 修饰符 [static] 返回值类型 方法名(参数列表) { |
- 修饰符,控制方法的访问权限,暂时只使用
public - static,可以省略,暂时不要省略
- 返回值类型。某些方法执行完毕后需要提供给调用者一些响应数据,这些数据就叫做返回值。返回值也需要数据类型,如果方法没有返回值,返回值类型需要写成
void - 方法名。给方法进行命名,遵守标识符规范,一般还是用小驼峰规则
- 参数列表。这叫做形参列表(形式参数列表)。某些方法调用时,需要从调用者那里传递一些数据,参数列表的作用就是在方法上定义好这些数据的个数、类型。格式:
数据类型 参数名, 数据类型 参数名 - 执行代码。方法调用过程中执行的代码。
- return 返回值。返回给调用者一些数据,供调用者进行处理。返回值必须与返回值类型一致,或者范围小于返回值类型。如果返回值类型为void,那么return语句可以省略,也可以写成
return;。当方法执行过程中遇到了return语句,方法会立即结束执行。
1 | /** |
方法的调用
1 | 数据类型 返回结果 = 方法名(参数列表); |
- 数据类型 返回结果。如果方法有返回值,可以声明一个变量来接收方法的运行结果。也可以不接收。如果是void,就没有返回值,不能声明变量接收。
- 方法名。被调用方法的方法名
- 参数列表。也叫作实际参数列表,可以传递常量和变量,实际参数的个数、数据类型,必须与形式参与一致,或者数据类型的范围小于形参范围。方法在调用时,不需要关注形式参数的参数名
1 | public static void main(String[] args) { |
方法的应用
1 | package methodstudy; |
注意:一般方法上的注释使用文档注释,并且使用 @param 描述每一个参数的含义,使用 @return 描述返回值的含义
随堂练习
编写一个方法,用来获取三个数之间的最大值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30package methodstudy;
public class Demo3Method {
public static void main(String[] args) {
System.out.println(getMax(3,6,5));
}
/**
* 编写一个方法,用来获取三个数之间的最大值。
* 参数列表:三个数字
* 返回值:最大值
*/
public static double getMax(double n1, double n2, double n3) {
// if(n1 > n2 && n1 > n3) {
// return n1;
// }else if(n2 > n1 && n2 > n3) {
// return n2;
// }else {
// return n3;
// }
if(n1 > n2 && n1 > n3) {
return n1;
}
if(n2 > n1 && n2 > n3) {
return n2;
}
return n3;
}
}写一个方法,该方法参数接收一个数字,输出这个数字层数的乘法表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25package methodstudy;
public class Demo4Method {
public static void main(String[] args) {
printTable(3);
}
/**
* 写一个方法,该方法参数接收一个数字,输出这个数字层数的乘法表。
*/
public static void printTable(int n) {
if(n <= 0 || n >= 10) {
System.out.println("您输入的层数不合法");
}else {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(j + "*" + i + "=" + (j*i) + "\t");
}
System.out.println();
}
}
}
}编写一个方法,接收三个数字,从小到大输出这三个数字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39package methodstudy;
public class Demo5Method {
public static void main(String[] args) {
printNum(10, 8, 15);
}
/**
* 编写一个方法,接收三个数字,从小到大输出这三个数字
*/
public static void printNum(int n1, int n2, int n3) {
// 假设法
int max = n1;
if(n2 > max) {
max = n2;
}
if(n3 > max) {
max = n3;
}
int min = n1;
if(n2 < min) {
min = n2;
}
if(n3 < min){
min = n3;
}
int second;
if(max != n1 && min!=n1) {
second = n1;
}else if(max != n2 && min != n2) {
second = n2;
}else {
second = n3;
}
System.out.println(min + ","+ second + "," + max);
}
}编写一个方法,用来计算一个数字的绝对值(负数的绝对值是其对应的正数,非负数的绝对值是它本身)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21package methodstudy;
public class Demo6Method {
public static void main(String[] args) {
System.out.println(getAbs(10));
System.out.println(getAbs(-10));
System.out.println(getAbs(0));
}
/**
* 编写一个方法,用来计算一个数字的绝对值
* (负数的绝对值是其对应的正数,非负数的绝对值是它本身)
*/
public static int getAbs(int n) {
if(n < 0) {
return -n;
}
return n;
}
}编写一个方法,对一个小数进行四舍五入取整操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38package methodstudy;
public class Demo7Method {
public static void main(String[] args) {
System.out.println(getRound(3.5));
System.out.println(getRound(-3.5));
System.out.println(getRound(3.4));
System.out.println(getRound(3.4999));
System.out.println(getRound(3));
System.out.println(getRound(0));
}
/**
* 编写一个方法,对一个小数进行四舍五入取整操作。
* 3.5
*/
public static int getRound(double n) {
// true为正数,false为负数
boolean flag = n >= 0;
n = getAbs(n);
int tmp = (int) n;
double point = n - tmp;
if(point < 0.5) {
return flag?tmp:-tmp;
}
return flag?tmp + 1:-(tmp + 1);
}
public static double getAbs(double n) {
if(n < 0) {
return -n;
}
return n;
}
}
方法调用过程
虚拟机中存在一个内存区域叫做栈内存。每个方法调用时,都会创建一个 栈帧,栈帧会按照方法调用的顺序入栈,当某个方法调用完毕后,这个栈帧就会出栈。

方法的重载
在同一个类中,允许有一个以上的同名方法,并且他们的参数个数或参数类型不同
返回值不同,不是重载方法
形参名称不同,不是重载方法
方法修饰符不同,不是重载方法
1 | package methodstudy; |
万年历
思路分析
- 需要输出万年历,就需要确定某个月的1号在这个月是星期几
- 如何确定?我们需要知道一个日期,这个日期是星期几是确定的,以这个日期为基准进行计算(1900年1月1日 星期一)
- 如何计算?(方法)比如想计算1904年3月1日是星期几,需要计算4*365+31+29+1,确定3月1日距1900年有多少天,再用天数取模7计算得余数,根据余数确定星期几
- 计算天数的过程中需要判断一个年份是否为闰年(方法)。如果一个年份能被400整除就是闰年,否则如果能被4整除但不能被100整除就是闰年。闰年需要注意的是2月有29天,全年有366天
- 从1号输出日历,每一星期为一个轮回
1 | package calendar; |
开发技巧
- 开发之前需要先分析需求,分析好每一步,以及每一步可能存在的问题
- 写代码讲究“一气呵成”,即编写过程中需要创建那些方法,可以先当做它已经有了,并且数据是正确的,按照这个过程先把外层写完,之后再去分别实现每一个方法,每一个方法内部又是分析每一步再去编写
- 编写代码的过程中,不要把所有的代码都写到一个main中,应该合理的抽取方法,把一个大问题拆解成一个一个的小问题
- 编写的过程中,写一点测一点,不要等全部写完了再测试