# 顺序结构

# 选择结构

  • 选择结构:根据条件来选择性地执行某段代码

# if 语句

  • 语法结构

    if (boolean 表达式 或 boolean 变量) {
        条件执行体 // 为 true 时执行
    }
    
    1
    2
    3
  • 执行流程

if语句

  • if (boolean 表达式) 后没有 ;

# if-else 语句

  • 语法结构

  • else 的隐含条件是对前面条件取反

    if (boolean 表达式 或 boolean 变量) {
        条件执行体 1 // 为 true 时执行 
    } else {
        条件执行体 2 // 为 false 时执行
    }
    
    1
    2
    3
    4
    5
  • 执行流程

if-else语句

  • 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
  • 执行流程

if-elseif-else语句

  • 不能单独使用 else if
  • 可以不需要 else,至少一个 else if

# switch 语句

  • 语法结构

    switch (整型表达式) {
        case1:
            执行语句 1;
            break; // 注意是否要写 break
        case2:
            执行语句 2;
            break;
        ...
        case 值 n:
            执行语句 n;
        break;
        default:
            以上值都不匹配时执行的语句; // 不用写 break
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
  • 执行流程

if-elseif-else语句

  • switch 语句适用于对多个整型值进行匹配判断,从而实现条件的分支控制,即“整型表达式 == int类型的值”

  • switch 语句后的表达式的数据类型只能是 byte、short、char、int 四种整数类型,枚举类型和 String 类型(从 Java 7 才允许),不能是 boolean 类型

  • switch 语句支持的基本数据类型只有四种:byteshortcharint不支持 long 类型,本质:switch 仅仅只能支持 int 类型(byte、short、char 会自动提升为 int 类型)

  • switch 执行的时会把入口 case 之后的 case 统统忽略,会一直往下执行,直到遇到 breakreturn (穿透)

  • 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循环

  • while 循环特点:先判断表达式,若为 true 就执行循环体,否则,跳过循环体
  • while 循环 和 do-while 循环 的循环体至少有 1 条语句用于对循环次数的控制(死循环除外)

# do-while 循环

  • 语法结构

    do {
        循环体;
        迭代语句; // 自增或自减,用于对循环次数的控制
    } while (boolean 表达式);
    
    1
    2
    3
    4
  • 执行流程

do-while循环

  • do while 循环特点:先执行一次循环体,再判断表达式,若为 true 就执行循环体,否则,跳过循环体
  • while 循环 和 do-while 循环 的循环体至少有 1 条语句用于对循环次数的控制(死循环除外)

# for 循环

  • 语法结构

    for (初始化语句; boolean 表达式; 迭代语句) {
        循环体;
    }
    
    1
    2
    3
  • 执行流程

for循环

# foreach 循环

  • jdk1.5 开始提供,用于循环遍历数组和集合

  • 语法格式

    for(type variableName : array | collection) {
        // variableName 自动迭代访问每个元素...
    }
    
    1
    2
    3
  • type 是数组元素或集合元素的类型,variableName 是一个形参名,foreach 循环将自动将数组元素、集合元素依次赋给该临时变量

  • 使用 foreach 循环迭代数组元素时,无法改变数组元素的值,因此不要对 foreach 的循环变量进行赋值

  • 遍历数组时使用的是原始 for 循环,遍历集合时使用的是 Iterator 迭代器

# 死循环

while (true) {
}

do {
} while (true)

for ( ; ; ) {
}
1
2
3
4
5
6
7
8

# 循环选择

  • 事先不知道循环次数,使用 while 循环或 do-while 循环,至少执行一次使用 do-while 循环
  • 事先知道循环次数,优先使用 for 循环
  • 死循环,推荐使用 while 循环

# 嵌套循环

  • 重复的操作(内层循环) 需要做 N 次(外层循环)
  • 确定:循环的是什么,要循环的次数
  • 嵌套 for 循环性能优化:
    1. 将循环变量的声明放在循环外
    2. 将循环次数少的作为外层循环

# 循环控制

  • break结束当前 break 所在的整个循环
  • continue跳过 continue 所在的本次循环剩下语句,开始下一次循环
  • return结束 return 所在的方法
  • 控制外层循环
    • 在外层循环开始前使用标签标识一个外层循环,如 outer:
    • 在 break 或 continue 后紧跟标签名,如 break outer; 或 continue outer;
  • 三者相同点:在其后不能写语句(这个语句与其在同一个花括号中),否则编译报错
Updated at: 2024-04-28 10:45:41