选择结构与循环结构
选择结构
if-else 结构案例说明
import java.util.Scanner;
/**
* 输入三个整数分别存入变量num1、num2、num3中
* 对它们进行排序(使用 if-else)并从小到大输出
*/
public class Test_01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("请输入第一个整数:");
int num1 = input.nextInt();
System.out.println("请输入第二个整数:");
int num2 = input.nextInt();
System.out.println("请输入第三个整数:");
int num3 = input.nextInt();
// 实现思路:嵌套 if
if (num1 >= num2) {
if (num1 <= num3) {
System.out.println(num2 + "<" + num1 + "<" + num3);
} else if (num2 <= num3) {
System.out.println(num2 + "<" + num3 + "<" + num1);
} else if (num3 <= num2) {
System.out.println(num3 + "<" + num2 + "<" + num1);
}
} else {
if (num2 <= num3) {
System.out.println(num1 + "<" + num2 + "<" + num3);
} else if (num1 <= num3) {
System.out.println(num1 + "<" + num3 + "<" + num2);
} else if (num3 <= num1) {
System.out.println(num3 + "<" + num1 + "<" + num2);
}
}
// 案例
ifTheUseOf();
}
/**
* if 有/没有括号时的使用
*/
public static void ifTheUseOf() {
int i = 10;
// 案例一
if (i > 5) {
if (i < 2)
System.out.println("1");
/*
如果不给 if 结构加上大括号,那么就只能影响到下面的第一行数据
所以这里两行输出语句,如果满足了条件,才会输出 1
如果没有满足条件,那么就只会输出 2
*/
System.out.println("2");
} else {
System.out.println("3");
}
//案例二
if (i > 5)
if (i < 2)
System.out.println("1");
/*
如果在使用多重if的时候都没有加上括号,它不会导致报错
但是它最后的else会采用就近原则
比如这里的 else 离 if (i < 2) 比较近,所以它就是这个if结构的else
而第一个 if (i > 5) 就没有了 else 层
*/
else
System.out.println("3");
}
}
if 后面的大括号在只有一行的时候是可以省略的,但是不建议省略!
switch-case 结构的使用
switch 中的表达式只能是六种数据类型,分别是:
byte、short、char、int、String(JDK1.7 新增的)、枚举类型(JDK1.5 新增的)
基本使用
public class Test_03 {
public static void main(String[] args) {
int i = 3;
switch (i) {
case 0:
System.out.println("zero");
case 1:
System.out.println("noe");
case 2:
System.out.println("tow");
case 3:
System.out.println("three");
default:
System.out.println("other");
}
/**
* 看到上面这个结构很多人可能第一反应觉得最后输出的是 three,但其实不是
* 因为没有 break 关键字的使用,所以程序会继续往下运行
* 所以最后输出的结果为 three 和 other
* 现在在给大家看一下 加上后的效果:
*/
switch (i) {
case 0:
System.out.println("zero");
break;
case 1:
System.out.println("noe");
break;
case 2:
System.out.println("tow");
break;
case 3:
//加上break后就只会输出这一个,因为执行完break后就会跳出当前的整个结构
System.out.println("three");
break;
default:
System.out.println("other");
break;
}
}
}
小案例
判断某个学生是否考试及格了
public class Test_04 {
public static void main(String[] args) {
//如果需要使用switch判断一个学生成绩是否及格,这个时候如果从1写到100的话过于麻烦,所以就可以使用运算符的方式来编写
int age = 59; //假设分数为59
//第一种方式:
switch (age / 10) {
case 0:
System.out.println("不及格");
break;
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;
case 8:
System.out.println("良好");
break;
case 9:
System.out.println("优秀");
break;
case 10:
System.out.println("优秀");
break;
default:
System.out.println("成绩有误!");
break;
}
/**
* 虽然上面这种方法减少了很多代码,但是还是会有很多代码且很多语句相同的情况
* 这个时候就可以考虑使用switch中的合并方式
*/
//第二种方式:
switch (age / 10) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
System.out.println("不及格");
break;
case 6:
case 7:
System.out.println("及格");
break;
case 8:
case 9:
case 10:
System.out.println("优秀");
break;
default:
System.out.println("成绩有误!");
break;
}
/**
* 其实还有更优的解决方案,上面的这些例子主要是为了让大家知道有这些方法可以使用
* 满分100分,60分算及格:以下这种方式虽然没有优秀那些分类了,但是却减少了很多的代码量
*/
//第三种方式:
switch (age / 60) {
case 0:
System.out.println("不及格");
break;
case 1:
System.out.println("及格");
break;
default:
System.out.println("成绩有误!");
break;
}
}
}
循环结构
所有循环结构的四个组成部分:
- 初始化部分
- 循环条件部分(boolean类型)
- 循环体部分
- 迭代条件部分
for 循环的使用
语法:
for(初始化部分;循环条件;迭代部分){
//循环部分
}
for 循环的执行顺序:
初始化部分(只执行一次) —> 循环条件 —> 循环部分 —> 迭代部分
练习
public class Test_06 {
public static void main(String[] args) {
//练习1:遍历1-100的值,遇到3的倍数时打印foo,遇到5的倍数时打印biz,遇到7的倍数时打印baz,都满足时都进行打印
for (int i = 1; i <= 100; i++) {
//因为可能有些值会满足两个条件的,所有这里不能使用多重if,比如15满足了都是3和5的倍数,所以这里需要分开写多个if
System.out.print(i);
if (i % 3 == 0) {
System.out.print("---foo");
}
if (i % 5 == 0) {
System.out.print("---biz");
}
if (i % 7 == 0) {
System.out.print("---baz");
}
System.out.println();
}
/**
* 练习2:输入两个正整数 m 和 n,求其最大公约数和最小公倍数
* 比如:12 和 20 的最大公约数为 4,最小公倍数为 60
*/
Scanner input = new Scanner(System.in);
System.out.println("第一个正整数为:");
int m = input.nextInt();
System.out.println("第二个正整数为:");
int n = input.nextInt();
//1.获取最大公约数,既可以被12整除又可以被20整除的数
//获取两个数中的最小值
int min = (m <= n) ? m : n;
for (int i = min; i >= 1; i--) {
if (m % i == 0 && n % i == 0) {
System.out.println(i);
break; //一旦在循环中执行break就会跳出当前循环
}
}
//2.获取最小公倍数,12*2后的数和20*2后的数相同,取最小的那个,就是60(12+12+12+12+12 = 20+20+20)
//获取两个数中的最大值
int max = (m >= n) ? m : n;
for (int i = max; i <= m * n; i++) {
if (i % n == 0 && i % m == 0) {
System.out.println(i);
break;
}
}
/**
* 水仙花运算的问题解决方案
* 水仙花数判断要求(153 = 1*1*1+5*5*5+3*3*3)
*/
System.out.println("100-1000中的水仙花数有:");
for (int i = 100; i < 1000; i++) {
int ge = i % 10; //15.3 -> 3
int shi = i / 10 % 10; //1.53 -> 5
int bai = i / 10 / 10 % 10; //0.153 -> 1
//进行判断
if (i == (ge * ge * ge + shi * shi * shi + bai * bai * bai)) {
System.out.println(i);
}
}
}
}
while 循环的使用
语法:
初始化部分
while(循环条件){
//循环部分
//迭代部分
}
执行顺序:
初始化部分(只执行一次) —> 循环条件 —> 循环部分 —> 迭代部分(一定要记得添加迭代部分,不然容易导致死循环)
for 循环和 while 循环的说明:
-
for 循环和 while 循环是可以相互转换的!
-
for 循环和 while 循环的初始化条件部分的作用域不同!for 的条件变量无法在外面使用,而while的可以
while 案例
public class Test_07 {
public static void main(String[] args) {
// while 循环的使用
flattenMap();
}
/**
* 简单使用
*/
public static void flattenMap() {
// 初始化
int i = 10;
// 设置循环条件
while (i < 20) {
// 循环部分
System.out.println("i = " + i);
//迭代部分
i++;
}
}
}
do-while 循环的使用
语法:
初始化部分
do{
//循环部分
//迭代部分
}while(循环条件);
执行顺序:
初始化部分(只执行一次) —> 循环部分 —> 迭代部分 —> 循环条件
说明:
- do-while 循环至少会执行一次循环部分
- 在实际开发中,for 和 while 循环的使用度会比 do-while 要多很多
do-while 案例
public class Test_08 {
public static void main(String[] args) {
// 初始化
int i = 10;
do {
// 循环部分
System.out.println("i = "+i);
// 迭代部分
i++;
// 循环条件
}while (i > 20);
}
}
嵌套循环的使用
public class Test_09 {
public static void main(String[] args) {
// 打印直角三角形
rightTriangle();
// 打印倒直角三角形
invertedTriangle();
// 打印三角形
triangle();
//九九乘法表
haskell();
}
/**
* 打印直角三角形
*/
public static void rightTriangle() {
// 打印五行
for (int i = 0; i < 5; i++) {
/*
每行显示几个
需求:输出五行,每行增加一个*,从而实现一个直角三角形
实现逻辑:j<i+1 -> 第一次 = 0 < 0+1 -> 循环一次 -> *
-> 第二次 = 0 < 1+1 -> 循环两次 -> **
......
以此循环,每次 j 都是从 0 开始,而 i 则是迭代后的数据,这样每次循环打印的个数就不一样了
*/
for (int j = 0; j < i + 1; j++) {
System.out.print("*");
}
System.out.println();
}
}
/**
* 打印倒的直角三角形
*/
public static void invertedTriangle() {
// 方式一
// for (int i = 0; i < 5; i++) {
// for (int j = 5; j > i; j--) {
// System.out.print("*");
// }
// System.out.println();
// }
// 方式二
for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 6 - i; j++) {
System.out.print("*");
}
System.out.println();
}
}
/**
* 打印三角形
*/
public static void triangle() {
for (int i = 0; i < 5; i++) {
for (int j = 5; j > i + 1; j--) {
System.out.print(" ");
}
for (int k = 1; k < (i + 1) * 2; k++) {
System.out.print("*");
}
System.out.println();
}
}
/**
* 九九乘法表
*/
public static void haskell() {
for (int i = 1; i < 10; i++) {
for (int j = 1; j < i + 1; j++) {
System.out.print(i + "*" + j + "=" + (i * j) + "\t");
}
System.out.println();
}
}
}
案例
/**
* 查找 1-100 以内的质数
*/
public class Test_11 {
public static void main(String[] args) {
// 获取当前时间距离 1970-01-01 00:00:00 的毫秒数
long start = System.currentTimeMillis();
// 遍历 10000 以内的自然数
label:
for (int i = 2; i <= 10000; i++) {
// j:被 i 去除
for (int j = 2; j <= Math.sqrt(i); j++) {
// 被 i 除尽后直接跳过指定的当次循环,直接开始执行下一次循环
if (i % j == 0) {
continue label;
}
}
System.out.println(i);
}
// 获取当前时间距离 1970-01-01 00:00:00 的毫秒数
long end = System.currentTimeMillis();
System.out.println("当前程序所耗费的时间为:" + (end - start));
}
}