# 顺序结构
# 选择结构
- 选择结构:根据条件来选择性地执行某段代码
# if 语句
语法结构
if (boolean 表达式 或 boolean 变量) { 条件执行体 // 为 true 时执行 }
1
2
3执行流程
- if (boolean 表达式) 后没有
;
# if-else 语句
语法结构
else 的隐含条件是对前面条件取反
if (boolean 表达式 或 boolean 变量) { 条件执行体 1 // 为 true 时执行 } else { 条件执行体 2 // 为 false 时执行 }
1
2
3
4
5执行流程
if-else 语句和三元运算符: 从语义上二者的含义相同;
从本质上说,if-else 是语句结构,三元运算符是一种运算符号,
三元运算符运算结束后会得到一个结果,
而 if-else,不能返回什么结果,只能控制语句的执行流程。不能直接使用 else 语句.
# if-else if-else 语句
语法结构
if (boolean 表达式 A) { 条件执行体 1 // A为 true 时执行 } else if (boolean 表达式 B) { 条件执行体 2 // B为 true 时执行 } else { 条件执行体 3 // 为 false 时执行 }
1
2
3
4
5
6
7执行流程
- 不能单独使用 else if
- 可以不需要 else,至少一个 else if
# switch 语句
语法结构
switch (整型表达式) { case 值 1: 执行语句 1; break; // 注意是否要写 break case 值 2: 执行语句 2; break; ... case 值 n: 执行语句 n; break; default: 以上值都不匹配时执行的语句; // 不用写 break }
1
2
3
4
5
6
7
8
9
10
11
12
13
14执行流程
switch 语句适用于对多个整型值进行匹配判断,从而实现条件的分支控制,即“整型表达式 == int类型的值”
switch 语句后的表达式的数据类型只能是 byte、short、char、int 四种整数类型,枚举类型和 String 类型(从 Java 7 才允许),不能是 boolean 类型
switch 语句支持的基本数据类型只有四种:
byte
、short
、char
、int
,不支持 long 类型,本质:switch 仅仅只能支持 int 类型(byte、short、char 会自动提升为 int 类型)switch 执行的时会把入口 case 之后的 case 统统忽略,会一直往下执行,直到遇到
break
或return
(穿透)default
一般放在 switch 的最后,也不需要写 break提前 if 判断帮助 CPU 分支预测 (opens new window)
- 现代 CPU 都支持分支预测(branch prediction)和指令流水线(instruction pipeline),这两个结合可以极大提高 CPU 效率。对于像简单的 if 跳转,CPU 是可以比较好地做分支预测的。但是对于 switch 跳转,CPU 则没有太多的办法。switch 本质上是据索引,从地址数组里取地址再跳转。
- 要提高代码执行效率,一个重要的原则就是尽量避免 CPU 把流水线清空,那么提高分支预测的成功率就非常重要。
- 对于代码里,如果某个 switch 分支概率很高,可以考虑代码层面帮 CPU 把判断提前(即考虑单独提前 if 判断),来提高代码执行效率。
for (int i = 0; i < plan.size; ++i) { ChannelState state = plan.states[i]; if (state == ChannelState.RECEIVED) { result += ChannelState.RECEIVED.ordinal(); } else { switch (state) { case CONNECTED: result += ChannelState.CONNECTED.ordinal(); break; case SENT: result += ChannelState.SENT.ordinal(); break; case DISCONNECTED: result += ChannelState.DISCONNECTED.ordinal(); break; case CAUGHT: result += ChannelState.CAUGHT.ordinal(); break; } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 总结
- if 语句:针对单个条件判断
- if-else 语句:针对两个相斥条件判断
- if-else if-else 语句:针对多个相斥条件判断(
范围
) - switch 语句:针对多个相斥条件判断(
整型值
)
# 循环结构
- 循环结构:根据循环条件重复执行某段代码
- 定义对象、变量、获取数据库连接等操作尽量移至循环体外处理
# while 循环
语法结构
while (boolean 表达式) { 循环体; 迭代语句; // 自增或自减,用于对循环次数的控制 }
1
2
3
4执行流程
- while 循环特点:先判断表达式,若为 true 就执行循环体,否则,跳过循环体
- while 循环 和 do-while 循环 的循环体至少有 1 条语句用于对循环次数的控制(死循环除外)
# do-while 循环
语法结构
do { 循环体; 迭代语句; // 自增或自减,用于对循环次数的控制 } while (boolean 表达式);
1
2
3
4执行流程
- do while 循环特点:先执行一次循环体,再判断表达式,若为 true 就执行循环体,否则,跳过循环体
- while 循环 和 do-while 循环 的循环体至少有 1 条语句用于对循环次数的控制(死循环除外)
# for 循环
语法结构
for (初始化语句; boolean 表达式; 迭代语句) { 循环体; }
1
2
3执行流程
# foreach 循环
jdk1.5 开始提供,用于循环遍历数组和集合
语法格式
for(type variableName : array | collection) { // variableName 自动迭代访问每个元素... }
1
2
3type 是数组元素或集合元素的类型,variableName 是一个形参名,foreach 循环将自动将数组元素、集合元素依次赋给该临时变量
使用 foreach 循环迭代数组元素时,无法改变数组元素的值,因此不要对 foreach 的循环变量进行赋值
遍历数组时使用的是原始 for 循环,遍历集合时使用的是 Iterator 迭代器
# 死循环
while (true) {
}
do {
} while (true)
for ( ; ; ) {
}
2
3
4
5
6
7
8
# 循环选择
- 事先不知道循环次数,使用 while 循环或 do-while 循环,至少执行一次使用 do-while 循环
- 事先知道循环次数,优先使用 for 循环
- 死循环,推荐使用 while 循环
# 嵌套循环
- 重复的操作(内层循环) 需要做 N 次(外层循环)
- 确定:循环的是什么,要循环的次数
- 嵌套 for 循环性能优化:
- 将循环变量的声明放在循环外
- 将循环次数少的作为外层循环
# 循环控制
break
:结束当前 break 所在的整个循环continue
:跳过 continue 所在的本次循环剩下语句,开始下一次循环return
:结束 return 所在的方法- 控制外层循环
- 在外层循环开始前使用标签标识一个外层循环,如 outer:
- 在 break 或 continue 后紧跟标签名,如 break outer; 或 continue outer;
- 三者相同点:在其后不能写语句(这个语句与其在同一个花括号中),否则编译报错
← 02 数据类型和运算符 04 方法 →