专业的JAVA编程教程与资源

网站首页 > java教程 正文

90%程序员不知道的Java流程控制优化技巧,让你的代码更高效!

temp10 2025-04-30 19:29:05 java教程 2 ℃ 0 评论

本文将全面介绍Java中的流程控制结构,包括条件语句(if/else, switch)和循环结构(for, while, do-while),并提供丰富的示例代码和对比分析。

一、条件语句


结构

90%程序员不知道的Java流程控制优化技巧,让你的代码更高效!

语法

适用场景

特点

if

if (条件) { ... }

单一条件判断

最简单的条件结构

if-else

if (条件) { ... } else { ... }

二选一条件

处理true/false两种情况

if-else if-else

if (条件1) { ... } else if (条件2) { ... } else { ... }

多条件判断

依次检查多个条件

嵌套if

if (条件1) { if (条件2) { ... } }

复杂条件逻辑

条件中包含子条件

switch

java switch (变量) { case 值1: ... break; default: ... }

等值多分支

清晰的多路分支

switch表达式 (Java 12+)

java var result = switch (变量) { case 1 -> "A"; default -> "B"; };

多分支返回值

更简洁,直接返回结果


1. if语句

if语句是最基础的条件控制结构,根据布尔表达式的结果决定是否执行某段代码。

if (条件表达式) {
    // 条件为true时执行的代码
}

示例:判断天气是否适合出门

boolean isSunny = true;
if (isSunny) {
    System.out.println("今天天气晴朗,适合出门散步!");
}

2. if-else语句

当需要条件为false时执行另一段代码,可以使用if-else结构。

if (条件表达式) {
    // 条件为true时执行的代码
} else {
    // 条件为false时执行的代码
}

示例:判断用户年龄是否成年

int age = 17;
if (age >= 18) {
    System.out.println("您已成年,可以观看此内容。");
} else {
    System.out.println("您未成年,请家长陪同观看。");
}

3. if-else if-else多重条件

当有多个条件需要判断时,可以使用if-else if-else结构。

if (条件1) {
    // 条件1为true时执行的代码
} else if (条件2) {
    // 条件2为true时执行的代码
} else if (条件3) {
    // 条件3为true时执行的代码
} else {
    // 所有条件都为false时执行的代码
}

示例:考试成绩评级

int score = 85;
if (score >= 90) {
    System.out.println("优秀!");
} else if (score >= 80) {
    System.out.println("良好!");
} else if (score >= 60) {
    System.out.println("及格");
} else {
    System.out.println("不及格,需要努力!");
}

4. 嵌套if语句

if语句可以嵌套使用,实现更复杂的条件判断。

示例:判断年份是否为闰年

int year = 2024;
boolean isLeapYear = false;

if (year % 4 == 0) {
    if (year % 100 != 0) {
        isLeapYear = true;
    } else {
        if (year % 400 == 0) {
            isLeapYear = true;
        }
    }
}

if (isLeapYear) {
    System.out.println(year + "年是闰年");
} else {
    System.out.println(year + "年不是闰年");
}

5. switch语句

switch语句用于多分支选择,比多重if-else更清晰。

switch (表达式) {
    case 值1:
        // 代码块1
        break;
    case 值2:
        // 代码块2
        break;
    // 可以有任意数量的case语句
    default:
        // 默认代码块
}

示例:根据星期几安排活动

int dayOfWeek = 3;
String activity;

switch (dayOfWeek) {
    case 1:
        activity = "周一:团队会议";
        break;
    case 2:
        activity = "周二:代码审查";
        break;
    case 3:
        activity = "周三:学习新技术";
        break;
    case 4:
        activity = "周四:项目开发";
        break;
    case 5:
        activity = "周五:项目演示";
        break;
    case 6:
        activity = "周六:休息";
        break;
    case 7:
        activity = "周日:家庭日";
        break;
    default:
        activity = "无效的星期";
}

System.out.println(activity);

Java 12+增强的switch表达式

Java 12引入了更简洁的switch表达式语法:

String dayType = switch (dayOfWeek) {
    case 1, 2, 3, 4, 5 -> "工作日";
    case 6, 7 -> "周末";
    default -> "无效";
};
System.out.println("今天是" + dayType);

条件语句对比表

特性

if-else

switch

适用场景

范围判断、复杂条件

等值判断、多分支选择

可读性

简单条件时好,复杂条件时差

多分支时清晰

性能

条件多时可能较慢

使用跳转表,性能稳定

表达式类型

布尔表达式

整型、枚举、String(Java 7+)

灵活性

较低

可维护性

条件多时较差

分支多时较好

二、循环结构

结构

语法

适用场景

特点

for

for (初始化; 条件; 步进) { ... }

已知循环次数

控制变量在循环头定义

增强for

for (类型 变量 : 集合) { ... }

遍历数组/集合

简洁,无需索引

while

while (条件) { ... }

条件先验循环

可能一次都不执行

do-while

do { ... } while (条件);

条件后验循环

至少执行一次

1. for循环

for循环是最常用的循环结构,适合已知循环次数的情况。

for (初始化; 条件; 更新) {
    // 循环体
}

示例:打印乘法表

// 打印9x9乘法表
for (int i = 1; i <= 9; i++) {
    for (int j = 1; j <= i; j++) {
        System.out.print(j + "×" + i + "=" + (i * j) + "\t");
    }
    System.out.println(); // 换行
}

2. 增强for循环(foreach)

Java 5引入的增强for循环,用于遍历数组或集合。

for (元素类型 变量名 : 数组或集合) {
    // 循环体
}

示例:遍历数组

String[] fruits = {"苹果", "香蕉", "橙子", "葡萄"};
for (String fruit : fruits) {
    System.out.println("我喜欢吃" + fruit);
}

3. while循环

while循环在不确定循环次数,但知道循环条件时使用。

while (条件) {
    // 循环体
}

示例:猜数字游戏

import java.util.Scanner;
import java.util.Random;

public class GuessNumber {
    public static void main(String[] args) {
        Random random = new Random();
        int target = random.nextInt(100) + 1; // 1-100的随机数
        int guess;
        int attempts = 0;
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("猜数字游戏开始!(1-100)");
        
        while (true) {
            System.out.print("请输入你的猜测:");
            guess = scanner.nextInt();
            attempts++;
            
            if (guess < target) {
                System.out.println("太小了!");
            } else if (guess > target) {
                System.out.println("太大了!");
            } else {
                System.out.println("恭喜你猜对了!用了" + attempts + "次。");
                break;
            }
        }
        scanner.close();
    }
}

4. do-while循环

do-while循环先执行一次循环体,再判断条件,至少执行一次。

do {
    // 循环体
} while (条件);

示例:用户菜单选择

import java.util.Scanner;

public class MenuSystem {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int choice;
        
        do {
            System.out.println("\n==== 菜单系统 ====");
            System.out.println("1. 查看个人信息");
            System.out.println("2. 修改密码");
            System.out.println("3. 退出系统");
            System.out.print("请选择(1-3): ");
            
            choice = scanner.nextInt();
            
            switch (choice) {
                case 1:
                    System.out.println("显示个人信息...");
                    break;
                case 2:
                    System.out.println("修改密码功能...");
                    break;
                case 3:
                    System.out.println("感谢使用,再见!");
                    break;
                default:
                    System.out.println("无效选择,请重新输入!");
            }
        } while (choice != 3);
        
        scanner.close();
    }
}

循环结构对比表

特性

for循环

while循环

do-while循环

适用场景

已知循环次数

未知循环次数,但知道条件

至少执行一次,再检查条件

初始化

循环内部初始化

循环外部初始化

循环外部初始化

语法复杂度

中等

简单

中等

使用频率

可读性

循环次数明确时好

条件明确时好

需要至少执行一次时好

三、循环控制语句


语句

作用

适用场景

break

退出当前循环

满足条件时提前终止

continue

跳过本次迭代

跳过特定条件的处理

带标签break

退出指定循环

多层循环中跳出外层

带标签continue

继续指定循环

多层循环中继续外层


1. break语句

break用于立即退出当前循环或switch语句。

示例:查找数组中第一个负数

int[] numbers = {3, 5, -2, 7, -8, 4};
int firstNegative = 0;

for (int num : numbers) {
    if (num < 0) {
        firstNegative = num;
        break; // 找到第一个负数就退出循环
    }
}

System.out.println("第一个负数是:" + firstNegative);

2. continue语句

continue跳过当前循环的剩余部分,直接开始下一次循环。

示例:打印1-10的奇数

for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) {
        continue; // 跳过偶数
    }
    System.out.println("奇数:" + i);
}

3. 带标签的break和continue

Java支持标签,可以用于控制多层循环的跳出。

示例:矩阵中查找特定值

int[][] matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
};
int target = 5;
boolean found = false;

outerLoop: // 标签
for (int i = 0; i < matrix.length; i++) {
    for (int j = 0; j < matrix[i].length; j++) {
        if (matrix[i][j] == target) {
            found = true;
            System.out.println("找到" + target + "在位置(" + i + "," + j + ")");
            break outerLoop; // 跳出外层循环
        }
    }
}

if (!found) {
    System.out.println("未找到" + target);
}

四、高级流程控制技巧


特性

版本

优点

String in switch

Java 7+

支持字符串比较

switch表达式

Java 12+

可返回值,更简洁

yield返回值

Java 13+

switch中返回值

模式匹配instanceof

Java 16+

简化类型检查和转换

1. 使用Stream API进行流程控制(Java 8+)

Java 8引入的Stream API提供了更函数式的流程控制方式。

示例:过滤和遍历集合

import java.util.Arrays;
import java.util.List;

public class StreamExample {
    public static void main(String[] args) {
        List<String> languages = Arrays.asList("Java", "Python", "C++", "JavaScript", "Ruby");
        
        // 使用Stream过滤并打印长度大于4的语言
        languages.stream()
                 .filter(lang -> lang.length() > 4)
                 .forEach(System.out::println);
        
        // 并行处理
        languages.parallelStream()
                 .map(String::toUpperCase)
                 .forEachOrdered(System.out::println);
    }
}

2. 使用Optional避免空指针检查(Java 8+)

Optional可以帮助减少if-else的空值检查。

import java.util.Optional;

public class OptionalExample {
    public static void main(String[] args) {
        String name = "Alice";
        // String name = null;
        
        Optional.ofNullable(name)
                .ifPresentOrElse(
                    n -> System.out.println("Hello, " + n),
                    () -> System.out.println("Hello, Guest")
                );
    }
}

3. 模式匹配(Java 14+预览,16+正式)

Java 16引入了模式匹配的instanceof,简化了类型检查和转换。

public class PatternMatching {
    public static void main(String[] args) {
        Object obj = "Hello Java";
        
        // 传统方式
        if (obj instanceof String) {
            String s = (String) obj;
            System.out.println(s.toUpperCase());
        }
        
        // 模式匹配方式
        if (obj instanceof String s) {
            System.out.println(s.toUpperCase());
        }
    }
}

五、性能考虑与最佳实践


场景

推荐结构

原因

等值多分支

switch

可读性更好

范围判断

if-else

switch不支持

集合遍历

增强for

代码更简洁

需要索引

传统for

可以访问索引

至少执行一次

do-while

保证执行

条件复杂

if-else

更灵活


1. 循环性能优化

  • 减少循环内部的计算:将不依赖循环变量的计算移到循环外部
  • 使用增强for循环:遍历集合时比传统for循环更高效
  • 避免在循环中创建对象:特别是大量小对象


结构

性能考虑

优化建议

if-else

将最可能为true的条件放前面

减少判断次数

switch

使用跳转表,性能稳定

超过3个分支时优先使用

for

避免在条件中调用方法

提前计算循环次数

while

注意避免无限循环

确保条件会变为false

嵌套循环

内层循环应尽量简单

减少总迭代次数


优化示例:

// 不推荐的写法
for (int i = 0; i < list.size(); i++) {  // size()在每次迭代都调用
    // ...
}

// 推荐的写法
int size = list.size();  // 提前计算
for (int i = 0; i < size; i++) {
    // ...
}

// 最佳写法(遍历集合时)
for (String item : list) {
    // ...
}

2. 条件语句最佳实践

  • 将最可能为true的条件放在前面:提高条件判断效率
  • 避免深层嵌套:超过3层的嵌套应考虑重构
  • 使用卫语句(Guard Clauses):提前返回减少嵌套

卫语句示例:

// 传统嵌套写法
public void process(User user) {
    if (user != null) {
        if (user.isActive()) {
            if (user.hasPermission()) {
                // 核心逻辑
            } else {
                System.out.println("无权限");
            }
        } else {
            System.out.println("用户未激活");
        }
    } else {
        System.out.println("用户不存在");
    }
}

// 使用卫语句改进
public void process(User user) {
    if (user == null) {
        System.out.println("用户不存在");
        return;
    }
    
    if (!user.isActive()) {
        System.out.println("用户未激活");
        return;
    }
    
    if (!user.hasPermission()) {
        System.out.println("无权限");
        return;
    }
    
    // 核心逻辑
}

3. 选择适当的循环结构

场景

推荐循环结构

已知确切循环次数

for循环

需要遍历数组或集合

增强for循环

循环次数未知,但有明确终止条件

while循环

至少需要执行一次循环体

do-while循环

需要并行处理集合元素

parallelStream

六、常见问题与解决方案

1. 无限循环问题

问题代码:

while (true) {  // 缺少终止条件
    System.out.println("无限循环...");
}

解决方案:

boolean running = true;
while (running) {
    // 业务逻辑
    if (exitCondition) {
        running = false;  // 或使用break
    }
}

2. switch忘记break导致穿透

问题代码:

int day = 2;
switch (day) {
    case 1: System.out.println("周一");
    case 2: System.out.println("周二");  // 忘记break
    case 3: System.out.println("周三");
}
// 输出:周二 周三

解决方案:

int day = 2;
switch (day) {
    case 1: 
        System.out.println("周一");
        break;
    case 2: 
        System.out.println("周二");
        break;
    case 3: 
        System.out.println("周三");
        break;
}

或者使用Java 12+的switch表达式避免此问题:

switch (day) {
    case 1 -> System.out.println("周一");
    case 2 -> System.out.println("周二");
    case 3 -> System.out.println("周三");
}

3. 循环性能问题

问题代码:

for (int i = 0; i < expensiveOperation(); i++) {  // 每次循环都调用
    // ...
}

解决方案:

int count = expensiveOperation();  // 提前计算
for (int i = 0; i < count; i++) {
    // ...
}

七、实际应用案例

1. 用户登录验证

import java.util.Scanner;

public class LoginSystem {
    public static void main(String[] args) {
        String correctUsername = "admin";
        String correctPassword = "123456";
        int attempts = 3;
        Scanner scanner = new Scanner(System.in);
        
        while (attempts > 0) {
            System.out.print("用户名:");
            String username = scanner.nextLine();
            
            System.out.print("密码:");
            String password = scanner.nextLine();
            
            if (username.equals(correctUsername) {
                if (password.equals(correctPassword)) {
                    System.out.println("登录成功!");
                    break;
                } else {
                    attempts--;
                    System.out.println("密码错误!剩余尝试次数:" + attempts);
                }
            } else {
                attempts--;
                System.out.println("用户名不存在!剩余尝试次数:" + attempts);
            }
        }
        
        if (attempts == 0) {
            System.out.println("登录失败,账户已锁定!");
        }
        
        scanner.close();
    }
}

2. 购物车结算系统

import java.util.HashMap;
import java.util.Map;

public class ShoppingCart {
    public static void main(String[] args) {
        Map<String, Double> products = new HashMap<>();
        products.put("苹果", 5.5);
        products.put("香蕉", 3.2);
        products.put("牛奶", 8.0);
        products.put("面包", 6.5);
        
        Map<String, Integer> cart = new HashMap<>();
        cart.put("苹果", 2);
        cart.put("牛奶", 1);
        cart.put("面包", 3);
        
        double total = 0.0;
        System.out.println("购物清单:");
        System.out.println("商品\t单价\t数量\t小计");
        
        for (Map.Entry<String, Integer> entry : cart.entrySet()) {
            String product = entry.getKey();
            int quantity = entry.getValue();
            
            if (products.containsKey(product)) {
                double price = products.get(product);
                double subtotal = price * quantity;
                total += subtotal;
                
                System.out.printf("%s\t%.2f\t%d\t%.2f%n", 
                                product, price, quantity, subtotal);
            } else {
                System.out.println("警告:商品" + product + "已下架");
            }
        }
        
        System.out.printf("总计:%.2f%n", total);
        
        // 根据总金额提供折扣
        if (total > 100) {
            System.out.println("符合满100减20优惠!");
            total -= 20;
        } else if (total > 50) {
            System.out.println("符合满50减5优惠!");
            total -= 5;
        }
        
        System.out.printf("实付金额:%.2f%n", total);
    }
}

总结

Java流程控制是编程的基础,合理使用条件语句和循环结构可以:

  1. 使代码逻辑更清晰
  2. 提高代码执行效率
  3. 增强程序的可读性和可维护性
  4. 处理复杂的业务逻辑

记住以下关键点:

  • 根据场景选择合适的流程控制结构
  • 避免过度嵌套,保持代码扁平化
  • 注意循环和条件的性能影响
  • 利用Java新特性简化代码(如switch表达式、模式匹配)
  • 遵循最佳实践,编写干净、高效的代码

Java 流程控制就是群 “代码戏精”!if傲娇守门,for循环永动,稍有不慎,程序秒变 “失控现场”!

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表