java快速学习速查(3)

这个部分涉及的方面是循环结构,条件语句,switch case,Number&Math,Character,String,StringBuffer几个方面,对照查询学习

Java循环结构全面解析

循环是编程中控制流程的重要结构,Java提供了多种循环方式以满足不同场景的需求。下面我将系统地讲解Java中的循环结构及其应用。

一、循环结构类型

1. while循环

语法结构:

1
2
3
while (条件表达式) {
// 循环体
}

特点:

  • 先判断条件,后执行循环体
  • 可能一次都不执行
  • 适合不确定循环次数的场景

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 计算1-100的和
int sum = 0;
int i = 1;
while (i <= 100) {
sum += i;
i++;
}
System.out.println("Sum: " + sum);

// 读取用户输入直到输入quit
Scanner scanner = new Scanner(System.in);
String input = "";
while (!input.equals("quit")) {
System.out.print("请输入命令:");
input = scanner.nextLine();
System.out.println("你输入了:" + input);
}

2. do-while循环

语法结构:

1
2
3
do {
// 循环体
} while (条件表达式);

特点:

  • 先执行循环体,后判断条件
  • 至少执行一次循环体
  • 适合需要至少执行一次的场景

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 密码验证(至少验证一次)
String password;
Scanner scanner = new Scanner(System.in);
do {
System.out.print("请输入密码:");
password = scanner.nextLine();
} while (!password.equals("123456"));
System.out.println("密码正确!");

// 生成随机数直到大于0.9
double randomValue;
do {
randomValue = Math.random();
System.out.println("生成值:" + randomValue);
} while (randomValue <= 0.9);

3. for循环

语法结构:

1
2
3
for (初始化; 条件表达式; 更新表达式) {
// 循环体
}

特点:

  • 循环次数通常已知
  • 初始化、条件和更新都在一行
  • 适合确定循环次数的场景

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 打印乘法表
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();
}

// 遍历数组
int[] numbers = {10, 20, 30, 40, 50};
for (int i = 0; i < numbers.length; i++) {
System.out.println("第" + (i+1) + "个元素:" + numbers[i]);
}

4. 增强for循环(for-each)

语法结构:

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

特点:

  • 简化数组和集合的遍历
  • 无需索引变量
  • 不能修改原数组/集合元素

示例:

1
2
3
4
5
6
7
8
9
10
11
// 遍历数组
String[] fruits = {"Apple", "Banana", "Orange"};
for (String fruit : fruits) {
System.out.println(fruit);
}

// 遍历集合
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
for (int num : numbers) {
System.out.println(num * num);
}

二、循环控制语句

1. break语句

作用: 立即终止当前循环

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 查找第一个能被7整除的数
for (int i = 1; i <= 100; i++) {
if (i % 7 == 0) {
System.out.println("找到第一个能被7整除的数:" + i);
break;
}
}

// 多层循环中的break(只跳出最内层循环)
outer: for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
if (i * j > 6) {
System.out.println("i=" + i + ", j=" + j);
break outer; // 使用标签跳出外层循环
}
}
}

2. continue语句

作用: 跳过本次循环,进入下一次循环

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 打印1-10的奇数
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue;
}
System.out.println(i);
}

// 跳过空字符串处理
String[] words = {"hello", "", "world", null, "java"};
for (String word : words) {
if (word == null || word.isEmpty()) {
continue;
}
System.out.println(word.toUpperCase());
}

三、循环结构对比

特性 while do-while for for-each
执行顺序 先判断后执行 先执行后判断 先判断后执行 自动遍历
最少执行次数 0次 1次 0次 集合大小次
适用场景 条件控制循环 至少执行一次 固定次数循环 集合/数组遍历
循环变量作用域 外部声明 外部声明 内部声明 内部声明
是否可提前终止 是(break)

四、循环最佳实践

1. 避免无限循环

1
2
3
4
5
6
7
8
9
10
11
12
13
// 错误示例
while (true) { // 缺少终止条件
System.out.println("无限循环");
}

// 正确做法
boolean running = true;
while (running) {
// 处理逻辑
if (shouldStop()) {
running = false;
}
}

2. 循环性能优化

1
2
3
4
5
6
7
8
9
// 优化前(每次循环都计算length)
for (int i = 0; i < list.size(); i++) {...}

// 优化后(缓存length)
int size = list.size();
for (int i = 0; i < size; i++) {...}

// 倒序循环有时更快
for (int i = array.length - 1; i >= 0; i--) {...}

3. 嵌套循环优化

1
2
3
4
5
6
7
8
9
10
11
12
13
// 低效的嵌套循环
for (int i = 0; i < 1000; i++) {
for (int j = 0; j < 100; j++) {
// 内层循环次数多
}
}

// 优化后(减少外层循环次数)
for (int j = 0; j < 100; j++) {
for (int i = 0; i < 1000; i++) {
// 现在内层循环次数少
}
}

五、典型应用场景

1. 数据处理

1
2
3
4
5
6
7
// 计算平均值
double[] data = {12.5, 18.7, 11.2, 19.8, 15.3};
double sum = 0;
for (double d : data) {
sum += d;
}
double average = sum / data.length;

2. 文件读取

1
2
3
4
5
6
7
8
9
// 读取文件所有行
try (BufferedReader reader = new BufferedReader(new FileReader("data.txt"))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}

3. 游戏循环

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
boolean gameRunning = true;
while (gameRunning) {
// 处理输入
processInput();

// 更新游戏状态
updateGame();

// 渲染画面
render();

// 检查游戏结束条件
if (isGameOver()) {
gameRunning = false;
}
}

六、常见问题与陷阱

  1. 循环条件错误

    1
    2
    // 死循环(i永远不会等于10)
    for (int i = 0; i != 10; i += 2) {...}
  2. 浮点数循环

    1
    2
    3
    4
    5
    6
    7
    8
    // 不可靠的浮点数循环
    for (double d = 0.1; d != 1.0; d += 0.1) {...}

    // 正确做法
    for (int i = 1; i <= 10; i++) {
    double d = i * 0.1;
    // 使用d
    }
  3. 修改循环变量

    1
    2
    3
    4
    5
    for (int i = 0; i < 10; i++) {
    if (i == 5) {
    i = 8; // 直接修改循环变量,容易出错
    }
    }
  4. 集合遍历时修改

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    List<String> list = new ArrayList<>(Arrays.asList("a", "b", "c"));
    for (String s : list) {
    if (s.equals("b")) {
    list.remove(s); // 抛出ConcurrentModificationException
    }
    }

    // 正确做法:使用迭代器
    Iterator<String> it = list.iterator();
    while (it.hasNext()) {
    String s = it.next();
    if (s.equals("b")) {
    it.remove(); // 安全删除
    }
    }

Java条件语句全面解析

条件语句是编程中实现分支逻辑的基础结构,Java提供了多种条件语句来实现不同复杂度的判断逻辑。下面我将系统地讲解Java中的条件语句及其应用。

一、基础条件语句

1. 简单if语句

语法结构:

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

示例:

1
2
3
4
5
6
7
int score = 85;
if (score >= 60) {
System.out.println("及格");
}

// 单行语句可省略大括号(但不推荐)
if (score >= 90) System.out.println("优秀");

2. if-else语句

语法结构:

1
2
3
4
5
if (条件表达式) {
// 条件为true时执行
} else {
// 条件为false时执行
}

示例:

1
2
3
4
5
6
int age = 17;
if (age >= 18) {
System.out.println("已成年");
} else {
System.out.println("未成年");
}

3. 多重if-else语句

语法结构:

1
2
3
4
5
6
7
8
9
if (条件1) {
// 条件1为true时执行
} else if (条件2) {
// 条件2为true时执行
} else if (条件3) {
// 条件3为true时执行
} else {
// 以上条件都不满足时执行
}

示例:

1
2
3
4
5
6
7
8
9
10
11
12
int score = 78;
if (score >= 90) {
System.out.println("优秀");
} else if (score >= 80) {
System.out.println("良好");
} else if (score >= 70) {
System.out.println("中等");
} else if (score >= 60) {
System.out.println("及格");
} else {
System.out.println("不及格");
}

二、嵌套条件语句

1. 基本嵌套结构

1
2
3
4
5
6
7
8
9
if (条件1) {
if (条件2) {
// 条件1和条件2都为true时执行
} else {
// 条件1为true但条件2为false时执行
}
} else {
// 条件1为false时执行
}

2. 实际应用示例

1
2
3
4
5
6
7
8
9
10
11
12
int age = 20;
boolean hasLicense = true;

if (age >= 18) {
if (hasLicense) {
System.out.println("可以合法驾驶");
} else {
System.out.println("需要先考取驾照");
}
} else {
System.out.println("未达到法定驾驶年龄");
}

三、特殊条件表达式

1. 三元运算符

语法结构:

1
变量 = (条件) ? 表达式1 : 表达式2;

示例:

1
2
3
4
int a = 10, b = 20;
int max = (a > b) ? a : b;

String result = (score >= 60) ? "及格" : "不及格";

2. switch-case语句

语法结构:

1
2
3
4
5
6
7
8
9
10
11
switch (表达式) {
case1:
// 代码
break;
case2:
// 代码
break;
...
default:
// 默认代码
}

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
int day = 3;
String dayName;
switch (day) {
case 1: dayName = "星期一"; break;
case 2: dayName = "星期二"; break;
case 3: dayName = "星期三"; break;
case 4: dayName = "星期四"; break;
case 5: dayName = "星期五"; break;
case 6: dayName = "星期六"; break;
case 7: dayName = "星期日"; break;
default: dayName = "无效日期";
}
System.out.println(dayName);

Java 12+增强switch:

1
2
3
4
5
6
7
8
9
10
String dayName = switch (day) {
case 1 -> "星期一";
case 2 -> "星期二";
case 3 -> "星期三";
case 4 -> "星期四";
case 5 -> "星期五";
case 6 -> "星期六";
case 7 -> "星期日";
default -> "无效日期";
};

四、条件语句最佳实践

1. 代码风格建议

1
2
3
4
5
6
7
8
9
10
11
// 推荐:清晰的缩进和括号
if (condition) {
// 代码
} else {
// 代码
}

// 不推荐:省略括号可能导致错误
if (condition)
doSomething();
doSomethingElse(); // 这行不在if块内!

2. 条件表达式优化

1
2
3
4
5
6
7
8
9
10
11
12
13
// 不推荐:嵌套过深
if (a > b) {
if (c > d) {
if (e > f) {
// 代码
}
}
}

// 推荐:使用逻辑运算符简化
if (a > b && c > d && e > f) {
// 代码
}

3. 提前返回模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 不推荐:多层嵌套
public boolean isValid(User user) {
if (user != null) {
if (user.getName() != null) {
if (user.getAge() > 0) {
return true;
}
}
}
return false;
}

// 推荐:提前返回
public boolean isValid(User user) {
if (user == null) return false;
if (user.getName() == null) return false;
if (user.getAge() <= 0) return false;
return true;
}

五、常见问题与陷阱

1. 浮点数比较

1
2
3
4
5
6
7
8
9
10
11
// 错误方式
double d = 0.1 + 0.2;
if (d == 0.3) { // false!
System.out.println("相等");
}

// 正确方式
double epsilon = 1e-10;
if (Math.abs(d - 0.3) < epsilon) {
System.out.println("视为相等");
}

2. 空指针异常

1
2
3
4
5
6
7
8
String str = null;
// 错误方式
if (str.equals("test")) {...} // NullPointerException

// 正确方式
if ("test".equals(str)) {...} // 安全
// 或
if (str != null && str.equals("test")) {...}

3. switch语句注意点

1
2
3
4
5
6
7
8
9
10
11
12
13
int num = 2;
switch (num) {
case 1:
System.out.println("一");
case 2: // 匹配到这里
System.out.println("二"); // 会执行
case 3: // 没有break,继续执行
System.out.println("三"); // 也会执行
break;
default:
System.out.println("其他");
}
// 输出:二 三

六、实际应用案例

1. 登录验证

1
2
3
4
5
6
7
8
9
10
11
12
public void login(String username, String password) {
if (username == null || username.trim().isEmpty()) {
System.out.println("用户名不能为空");
} else if (password == null || password.length() < 6) {
System.out.println("密码长度至少6位");
} else if (!isValidUser(username, password)) {
System.out.println("用户名或密码错误");
} else {
System.out.println("登录成功");
// 跳转到主页面
}
}

2. 成绩等级判断

1
2
3
4
5
6
7
8
9
10
11
char determineGrade(int score) {
if (score < 0 || score > 100) {
throw new IllegalArgumentException("无效分数");
}

if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
}

3. 月份天数判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int getDaysInMonth(int year, int month) {
if (month < 1 || month > 12) {
throw new IllegalArgumentException("无效月份");
}

switch (month) {
case 4: case 6: case 9: case 11:
return 30;
case 2:
return (year % 400 == 0) || (year % 100 != 0 && year % 4 == 0) ? 29 : 28;
default:
return 31;
}
}

Java switch-case 语句全面解析

switch-case 是Java中用于多分支选择的结构,比多重if-else语句更加清晰易读。下面我将详细讲解switch-case的各种用法和特性。

一、基本语法结构

1
2
3
4
5
6
7
8
9
10
11
switch (表达式) {
case1:
// 代码块1
break;
case2:
// 代码块2
break;
...
default:
// 默认代码块
}

二、switch语句特性

1. 支持的数据类型

  • Java 7之前:byte, short, int, char
  • **Java 7+**:新增String类型
  • **Java 14+**:支持表达式形式(预览特性)

2. 执行流程

  1. 计算表达式的值
  2. 与case标签的值比较
  3. 匹配成功后执行对应的代码块
  4. 遇到break或执行到switch末尾时退出

3. break的重要性

1
2
3
4
5
6
7
8
9
10
11
int day = 2;
switch (day) {
case 1: System.out.println("周一");
case 2: System.out.println("周二"); // 从这里开始执行
case 3: System.out.println("周三"); // 继续执行(没有break)
default: System.out.println("其他"); // 继续执行
}
// 输出:
// 周二
// 周三
// 其他

三、完整使用示例

1. 传统写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class DayOfWeek {
public static void main(String[] args) {
int day = 3;
String dayName;

switch (day) {
case 1: dayName = "Monday"; break;
case 2: dayName = "Tuesday"; break;
case 3: dayName = "Wednesday"; break;
case 4: dayName = "Thursday"; break;
case 5: dayName = "Friday"; break;
case 6: dayName = "Saturday"; break;
case 7: dayName = "Sunday"; break;
default: dayName = "Invalid day";
}

System.out.println(dayName); // 输出:Wednesday
}
}

2. 多个case合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int month = 2;
int year = 2020;
int days = 0;

switch (month) {
case 1: case 3: case 5: case 7: case 8: case 10: case 12:
days = 31;
break;
case 4: case 6: case 9: case 11:
days = 30;
break;
case 2:
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0))
days = 29;
else
days = 28;
break;
default:
days = 0;
}
System.out.println("Days: " + days); // 输出:Days: 29

3. 字符串匹配(Java 7+)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
String fruit = "Apple";
switch (fruit) {
case "Orange":
System.out.println("Selected Orange");
break;
case "Apple":
System.out.println("Selected Apple"); // 输出这行
break;
case "Banana":
System.out.println("Selected Banana");
break;
default:
System.out.println("Unknown fruit");
}

四、Java 12+ 新特性

1. 箭头语法(->)

1
2
3
4
5
6
7
int day = 3;
String dayType = switch (day) {
case 1, 2, 3, 4, 5 -> "Weekday"; // 多case匹配
case 6, 7 -> "Weekend";
default -> "Invalid";
};
System.out.println(dayType); // 输出:Weekday

2. yield返回值(Java 13+)

1
2
3
4
5
6
7
8
9
10
String season = switch (month) {
case 12, 1, 2 -> "Winter";
case 3, 4, 5 -> "Spring";
case 6, 7, 8 -> {
System.out.println("Summer months");
yield "Summer"; // 使用yield返回值
}
case 9, 10, 11 -> "Autumn";
default -> "Unknown";
};

五、最佳实践

  1. 总是包含default分支:处理未预期的值
  2. 不要省略break:除非有意使用fall-through特性
  3. 保持case分支简洁:复杂逻辑应提取为方法
  4. 利用多case合并:简化相同处理的case
  5. 考虑使用枚举:提高类型安全性

六、与if-else对比

特性 switch-case if-else
可读性 多分支时更清晰 分支多时难以阅读
性能 通常使用跳转表更高效 需要顺序比较
表达式类型 有限支持 支持任何布尔表达式
适用场景 离散值精确匹配 范围判断或复杂条件

七、常见问题

  1. 忘记break导致意外fall-through

    1
    2
    3
    4
    5
    // 错误示例
    switch (x) {
    case 1: System.out.println("1"); // 忘记break
    case 2: System.out.println("2"); break;
    }
  2. case值重复

    1
    2
    3
    4
    switch (x) {
    case 1: ... break;
    case 1: ... break; // 编译错误:重复的case
    }
  3. 使用null导致NPE

    1
    2
    String s = null;
    switch (s) { ... } // 抛出NullPointerException
  4. 类型不匹配

    1
    2
    long x = 10;
    switch (x) { ... } // 编译错误:不支持long类型

Java Number & Math 类全面解析

Java 提供了强大的数字处理能力,包括基本数据类型的包装类和丰富的数学运算工具。下面我将系统地讲解这些功能的使用方法和最佳实践。

一、Number 包装类体系

1. 包装类与基本类型对应关系

基本类型 包装类 继承关系
byte Byte → Number → Object
short Short → Number → Object
int Integer → Number → Object
long Long → Number → Object
float Float → Number → Object
double Double → Number → Object
char Character → Object
boolean Boolean → Object

2. 自动装箱与拆箱

1
2
3
4
5
6
7
8
9
10
11
// 自动装箱
Integer a = 10; // 编译器转换为 Integer.valueOf(10)
Double b = 3.14; // Double.valueOf(3.14)

// 自动拆箱
int c = a; // a.intValue()
double d = b; // b.doubleValue()

// 混合运算时的自动拆箱
Integer x = 5;
x = x + 10; // x拆箱→相加→结果装箱

3. 常用方法示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 字符串转换
int num = Integer.parseInt("123");
String str = Integer.toString(456);

// 比较大小
Integer x = 10, y = 20;
int compareResult = x.compareTo(y); // -1 (x < y)

// 类型转换
double d = x.doubleValue();

// 进制转换
String binary = Integer.toBinaryString(10); // "1010"
String hex = Integer.toHexString(255); // "ff"

二、Math 数学工具类

1. 基本数学运算

1
2
3
4
5
6
7
8
9
10
11
12
// 绝对值
Math.abs(-5.6); // 5.6

// 取整运算
Math.ceil(3.2); // 4.0 (向上取整)
Math.floor(3.8); // 3.0 (向下取整)
Math.round(3.5); // 4 (四舍五入)
Math.rint(3.5); // 4.0 (最接近的整数)

// 极值
Math.max(10, 20); // 20
Math.min(1.2, 3.4); // 1.2

2. 指数与对数

1
2
3
4
5
6
7
8
9
10
11
// 幂运算
Math.pow(2, 3); // 8.0 (2的3次方)
Math.exp(1); // 2.718... (e的1次方)

// 对数
Math.log(Math.E); // 1.0 (自然对数)
Math.log10(100); // 2.0 (以10为底)

// 平方根
Math.sqrt(16); // 4.0
Math.cbrt(27); // 3.0 (立方根)

3. 三角函数

1
2
3
4
5
6
7
8
9
10
11
12
// 角度转弧度
double radians = Math.toRadians(30); // 0.5236

// 三角函数
Math.sin(Math.PI/6); // 0.5 (30度正弦)
Math.cos(Math.PI/3); // 0.5 (60度余弦)
Math.tan(Math.PI/4); // 1.0 (45度正切)

// 反三角函数
Math.asin(0.5); // 0.5236 (≈π/6)
Math.acos(0.5); // 1.0472 (≈π/3)
Math.atan(1); // 0.7854 (≈π/4)

4. 随机数生成

1
2
3
4
5
6
7
8
9
// 生成[0,1)之间的随机double
double rand1 = Math.random();

// 生成[1,100]的随机整数
int rand2 = (int)(Math.random() * 100) + 1;

// Java 8+更好的方式
Random random = new Random();
int rand3 = random.nextInt(100) + 1; // [1,100]

三、数值处理高级技巧

1. 精确计算问题

1
2
3
4
5
6
7
// 浮点数精度问题
System.out.println(0.1 + 0.2); // 0.30000000000000004

// 使用BigDecimal解决
BigDecimal bd1 = new BigDecimal("0.1");
BigDecimal bd2 = new BigDecimal("0.2");
System.out.println(bd1.add(bd2)); // 0.3

2. 数值溢出处理

1
2
3
4
5
6
7
8
9
// 整数溢出
int max = Integer.MAX_VALUE;
int overflow = max + 1; // -2147483648 (溢出)

// 安全运算方法
Math.addExact(max, 1); // 抛出ArithmeticException

// 使用更大范围的类型
long safeResult = (long)max + 1;

3. 位运算操作

1
2
3
4
5
6
7
8
9
10
11
12
13
// 基本位运算
int a = 0b1100; // 12
int b = 0b1010; // 10
a & b; // 8 (0b1000)
a | b; // 14 (0b1110)
a ^ b; // 6 (0b0110)
~a; // -13 (0b...11110011)

// 位移运算
int c = 0b1100;
c << 2; // 48 (0b110000)
c >> 1; // 6 (0b0110)
c >>> 1; // 6 (无符号右移)

四、Java 8+ 新增数值API

1. 无符号数支持

1
2
3
4
5
6
7
8
// 无符号比较
Integer.compareUnsigned(-1, 1); // 1 (视为无符号数比较)

// 无符号转换
Long.toUnsignedString(-1); // "18446744073709551615"

// 无符号除法
Integer.divideUnsigned(-2, 2); // 2147483647

2. 数值溢出检查

1
2
3
4
5
6
7
// 安全运算方法
Math.addExact(100000, 200000); // 正常
Math.addExact(Integer.MAX_VALUE, 1); // 抛出异常

// 乘法检查
Math.multiplyExact(100000, 1000); // 正常
Math.multiplyExact(Integer.MAX_VALUE, 2); // 抛出异常

3. 数学增强方法

1
2
3
4
5
6
7
8
// 精确数学运算
Math.floorDiv(5, 2); // 2
Math.floorMod(5, 2); // 1

// 双曲函数
Math.sinh(1.0); // 双曲正弦
Math.cosh(1.0); // 双曲余弦
Math.tanh(1.0); // 双曲正切

五、最佳实践与性能考虑

  1. 优先使用基本类型:包装类有额外开销

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // 不好
    Integer sum = 0;
    for (int i = 0; i < 100; i++) {
    sum += i; // 反复装箱拆箱
    }

    // 好
    int sum = 0;
    for (int i = 0; i < 100; i++) {
    sum += i;
    }
  2. 缓存机制利用

    1
    2
    3
    4
    5
    6
    7
    Integer a = 127;
    Integer b = 127;
    System.out.println(a == b); // true (使用缓存)

    Integer c = 128;
    Integer d = 128;
    System.out.println(c == d); // false (超出缓存范围)
  3. 精确计算选择

    1
    2
    3
    4
    // 金融计算使用BigDecimal
    BigDecimal price = new BigDecimal("19.99");
    BigDecimal quantity = new BigDecimal("2.5");
    BigDecimal total = price.multiply(quantity).setScale(2, RoundingMode.HALF_UP);
  4. 数学函数优化

    1
    2
    3
    // 重复计算先缓存
    double sinValue = Math.sin(angle);
    double cosValue = Math.cos(angle);

    记住在关键性能路径上避免不必要的对象创建,并注意数值精度和溢出问题。

Java Character 类全面解析

Character 类是 Java 中用于操作单个字符的包装类,提供了丰富的字符操作方法。下面我将系统地讲解 Character 类的各种功能和使用场景。

一、Character 类基础

1. 创建 Character 对象

1
2
3
4
5
6
7
8
// 构造函数方式(Java 9后已废弃)
Character ch1 = new Character('A'); // 不推荐

// 自动装箱方式(推荐)
Character ch2 = 'B';

// valueOf 方法(推荐)
Character ch3 = Character.valueOf('C');

2. 基本方法

1
2
3
4
5
6
7
8
9
10
11
12
13
char c = 'a';

// 获取字符的Unicode值
int code = Character.getNumericValue(c);

// 判断字符类型
boolean isLetter = Character.isLetter(c); // true
boolean isDigit = Character.isDigit('7'); // true
boolean isSpace = Character.isWhitespace(' '); // true

// 大小写转换
char upper = Character.toUpperCase('a'); // 'A'
char lower = Character.toLowerCase('Z'); // 'z'

二、字符类型检测方法

1. 常用检测方法

方法名 描述 示例
isLetter(char ch) 判断是否是字母 isLetter('A') → true
isDigit(char ch) 判断是否是数字 isDigit('5') → true
isLetterOrDigit(char) 判断是否是字母或数字 isLetterOrDigit('_') → false
isWhitespace(char) 判断是否是空白字符 isWhitespace('\t') → true
isUpperCase(char) 判断是否是大写字母 isUpperCase('A') → true
isLowerCase(char) 判断是否是小写字母 isLowerCase('a') → true

2. Unicode 相关检测

1
2
3
4
5
6
7
8
9
10
11
// 判断是否是Java标识符起始字符
Character.isJavaIdentifierStart('$'); // true

// 判断是否是Java标识符部分字符
Character.isJavaIdentifierPart('_'); // true

// 判断是否是Unicode空格字符
Character.isSpaceChar('\u00A0'); // true

// 判断是否是代理字符
Character.isSurrogate('\uD800'); // true

三、字符转换操作

1. 大小写转换

1
2
3
4
5
6
7
8
// 单个字符转换
char upperA = Character.toUpperCase('a'); // 'A'
char lowerZ = Character.toLowerCase('Z'); // 'z'

// 整个字符串转换
String str = "Hello World";
String upperStr = str.toUpperCase(); // "HELLO WORLD"
String lowerStr = str.toLowerCase(); // "hello world"

2. 数字字符转换

1
2
3
4
5
6
// 字符数字转数值
int num = Character.getNumericValue('9'); // 9
int hex = Character.getNumericValue('A'); // 10 (十六进制)

// 数值转字符
char digit = Character.forDigit(15, 16); // 'f' (16进制)

3. 字符与Unicode

1
2
3
4
5
// 获取Unicode代码点
int codePoint = Character.codePointAt("ABC", 1); // 66 ('B')

// 代码点转字符
char[] chars = Character.toChars(0x1F600); // 😀

四、特殊字符处理

1. 转义字符

转义序列 Unicode 描述
\t \u0009 水平制表符
\b \u0008 退格
\n \u000a 换行
\r \u000d 回车
\f \u000c 换页
\' \u0027 单引号
\" \u0022 双引号
\\ \u005c 反斜杠

2. Unicode 处理

1
2
3
4
5
6
7
// 直接使用Unicode
char omega = '\u03A9'; // Ω
System.out.println(omega);

// 处理代理对(Surrogate Pair)
String emoji = "\uD83D\uDE00"; // 😀
int codePoint = emoji.codePointAt(0); // 128512

五、Character 常量

Character 类提供了许多有用的常量:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 基本类型大小
Character.SIZE; // 16 (bits)
Character.BYTES; // 2 (bytes)

// 特殊字符值
Character.MIN_VALUE; // '\u0000'
Character.MAX_VALUE; // '\uffff'

// Unicode常量
Character.MIN_CODE_POINT; // 0x000000
Character.MAX_CODE_POINT; // 0x10FFFF
Character.MIN_SURROGATE; // '\uD800'
Character.MAX_SURROGATE; // '\uDFFF'

六、实际应用示例

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
public class CharCounter {
public static void countChars(String str) {
int letters = 0;
int digits = 0;
int others = 0;

for (char c : str.toCharArray()) {
if (Character.isLetter(c)) {
letters++;
} else if (Character.isDigit(c)) {
digits++;
} else {
others++;
}
}

System.out.println("字母: " + letters);
System.out.println("数字: " + digits);
System.out.println("其他: " + others);
}

public static void main(String[] args) {
countChars("Hello123!你好");
}
}

2. 密码强度验证

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
public class PasswordValidator {
public static boolean isStrongPassword(String password) {
if (password == null || password.length() < 8) {
return false;
}

boolean hasUpper = false;
boolean hasLower = false;
boolean hasDigit = false;
boolean hasSpecial = false;

for (char c : password.toCharArray()) {
if (Character.isUpperCase(c)) hasUpper = true;
else if (Character.isLowerCase(c)) hasLower = true;
else if (Character.isDigit(c)) hasDigit = true;
else if (!Character.isLetterOrDigit(c)) hasSpecial = true;
}

return hasUpper && hasLower && hasDigit && hasSpecial;
}

public static void main(String[] args) {
System.out.println(isStrongPassword("Pass123!")); // true
System.out.println(isStrongPassword("weak")); // false
}
}

3. 驼峰命名转换

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
public class CamelCaseConverter {
public static String toCamelCase(String input) {
if (input == null || input.isEmpty()) {
return input;
}

StringBuilder result = new StringBuilder();
boolean nextUpper = false;

for (int i = 0; i < input.length(); i++) {
char current = input.charAt(i);

if (current == '_') {
nextUpper = true;
} else {
if (nextUpper) {
result.append(Character.toUpperCase(current));
nextUpper = false;
} else {
result.append(Character.toLowerCase(current));
}
}
}

return result.toString();
}

public static void main(String[] args) {
System.out.println(toCamelCase("hello_world")); // helloWorld
System.out.println(toCamelCase("MY_VAR_NAME")); // myVarName
}
}

七、性能考虑与最佳实践

  1. 避免不必要的装箱

    1
    2
    3
    4
    5
    6
    7
    // 不好
    Character ch = 'a';
    if (ch.equals('b')) {...}

    // 好
    char c = 'a';
    if (c == 'b') {...}
  2. 使用String处理字符串

    1
    2
    3
    4
    5
    6
    // 不要这样处理字符串
    Character[] chars = ...;

    // 应该使用String或char[]
    String str = ...;
    char[] chars = ...;
  3. 处理代理对

    1
    2
    3
    4
    5
    6
    String emoji = "😀";
    // 错误方式(会拆分成两个char)
    char first = emoji.charAt(0); // '\uD83D'

    // 正确方式(处理代码点)
    int codePoint = emoji.codePointAt(0); // 128512
  4. 使用Character常量

    1
    2
    3
    4
    5
    6
    7
    // 不要使用魔法值
    if (c == 9) {...}

    // 使用预定义常量
    if (c == '\t') {...}
    // 或
    if (c == Character.TAB) {...}

通过合理使用 Character 类,可以高效地处理各种字符操作需求,特别是在文本处理、输入验证和国际化应用中。记住在性能敏感的场景中优先使用基本类型 char,并注意 Unicode 特殊字符的处理。

Java String 类全面解析

String 类是 Java 中最常用的类之一,用于表示和操作文本数据。下面我将系统地讲解 String 类的各种功能和使用场景。

一、String 类基础

1. 创建 String 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
// 字面量方式(推荐)
String str1 = "Hello";

// 构造函数方式
String str2 = new String("World");

// 从字符数组创建
char[] charArray = {'J', 'a', 'v', 'a'};
String str3 = new String(charArray);

// 从字节数组创建
byte[] byteArray = {65, 66, 67};
String str4 = new String(byteArray); // "ABC"

2. 字符串池与内存管理

1
2
3
4
5
6
7
String s1 = "Java";      // 存储在字符串常量池
String s2 = "Java"; // 复用常量池中的"Java"
String s3 = new String("Java"); // 在堆上创建新对象

System.out.println(s1 == s2); // true (相同引用)
System.out.println(s1 == s3); // false (不同对象)
System.out.println(s1.equals(s3)); // true (内容相同)

二、字符串基本操作

1. 获取字符串信息

1
2
3
4
5
6
7
8
9
10
11
String str = "Hello World";

// 获取长度
int len = str.length(); // 11

// 获取指定位置字符
char ch = str.charAt(1); // 'e'

// 获取子字符串位置
int index = str.indexOf("World"); // 6
int lastIndex = str.lastIndexOf('o'); // 7

2. 字符串比较

方法名 描述 示例
equals(Object obj) 比较内容是否相同 "abc".equals("abc") → true
equalsIgnoreCase(String) 忽略大小写比较内容 "ABC".equalsIgnoreCase("abc") → true
compareTo(String) 按字典顺序比较 "a".compareTo("b") → -1
compareToIgnoreCase(String) 忽略大小写的字典顺序比较 "A".compareToIgnoreCase("a") → 0
startsWith(String) 检查是否以指定字符串开头 "Hello".startsWith("He") → true
endsWith(String) 检查是否以指定字符串结尾 "Hello".endsWith("lo") → true

三、字符串操作与转换

1. 字符串连接

1
2
3
4
5
6
7
8
9
10
// 使用 + 运算符
String s1 = "Hello" + " " + "World"; // "Hello World"

// 使用 concat 方法
String s2 = "Hello".concat(" World"); // "Hello World"

// 使用 StringBuilder (高性能)
StringBuilder sb = new StringBuilder();
sb.append("Hello").append(" ").append("World");
String s3 = sb.toString(); // "Hello World"

2. 字符串修改

1
2
3
4
5
6
7
8
9
10
11
String original = "Java Programming";

// 替换字符
String replaced = original.replace('a', 'o'); // "Jovo Progromming"

// 替换子串
String replacedAll = original.replaceAll("Java", "Python"); // "Python Programming"

// 获取子串
String substring1 = original.substring(5); // "Programming"
String substring2 = original.substring(5, 12); // "Program"

3. 大小写转换

1
2
3
4
5
6
7
String str = "Hello World";

// 转大写
String upper = str.toUpperCase(); // "HELLO WORLD"

// 转小写
String lower = str.toLowerCase(); // "hello world"

四、字符串格式化

1. 静态 format 方法

1
2
3
4
5
6
7
String name = "Alice";
int age = 25;
double score = 95.5;

// 格式化字符串
String info = String.format("Name: %s, Age: %d, Score: %.2f", name, age, score);
// "Name: Alice, Age: 25, Score: 95.50"

2. 常用格式说明符

说明符 适用类型 示例输出
%s 字符串 “Hello”
%d 十进制整数 123
%f 浮点数 3.141593
%.2f 保留两位小数 3.14
%c 字符 ‘A’
%b 布尔值 true
%n 平台相关的行分隔符 (换行)

五、字符串分割与正则表达式

1. 字符串分割

1
2
3
4
5
6
7
8
9
String str = "apple,orange,banana,grape";

// 简单分割
String[] fruits = str.split(",");
// ["apple", "orange", "banana", "grape"]

// 限制分割次数
String[] limited = str.split(",", 2);
// ["apple", "orange,banana,grape"]

2. 正则表达式匹配

1
2
3
4
5
6
7
String email = "test@example.com";

// 检查格式
boolean isValid = email.matches("^[\\w-]+@[\\w-]+\\.[a-z]{2,3}$"); // true

// 替换所有数字
String replaced = "a1b2c3".replaceAll("\\d", "-"); // "a-b-c-"

六、字符串与字符/字节数组转换

1. 字符数组转换

1
2
3
4
5
6
7
String str = "Hello";

// String → char[]
char[] charArray = str.toCharArray();

// char[] → String
String newStr = new String(charArray);

2. 字节数组转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
String str = "Hello";

// String → byte[] (使用默认编码)
byte[] byteArray = str.getBytes();

// byte[] → String
String newStr = new String(byteArray);

// 指定编码
try {
byte[] utf8Bytes = str.getBytes("UTF-8");
String fromUtf8 = new String(utf8Bytes, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}

七、实际应用示例

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
public class StringReverse {
public static String reverse(String input) {
if (input == null || input.isEmpty()) {
return input;
}

char[] chars = input.toCharArray();
int left = 0;
int right = chars.length - 1;

while (left < right) {
char temp = chars[left];
chars[left] = chars[right];
chars[right] = temp;
left++;
right--;
}

return new String(chars);
}

public static void main(String[] args) {
System.out.println(reverse("Hello")); // "olleH"
System.out.println(reverse("Java")); // "avaJ"
}
}

2. 检查回文字符串

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
public class PalindromeChecker {
public static boolean isPalindrome(String str) {
if (str == null) {
return false;
}

str = str.toLowerCase().replaceAll("[^a-z0-9]", "");
int left = 0;
int right = str.length() - 1;

while (left < right) {
if (str.charAt(left) != str.charAt(right)) {
return false;
}
left++;
right--;
}

return true;
}

public static void main(String[] args) {
System.out.println(isPalindrome("A man, a plan, a canal: Panama")); // true
System.out.println(isPalindrome("racecar")); // true
System.out.println(isPalindrome("hello")); // false
}
}

3. 统计单词出现次数

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
import java.util.HashMap;
import java.util.Map;

public class WordCounter {
public static Map<String, Integer> countWords(String text) {
Map<String, Integer> wordCount = new HashMap<>();

if (text == null || text.isEmpty()) {
return wordCount;
}

String[] words = text.split("\\s+");

for (String word : words) {
word = word.toLowerCase().replaceAll("[^a-z]", "");
if (!word.isEmpty()) {
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);
}
}

return wordCount;
}

public static void main(String[] args) {
String text = "Hello world hello Java world Java";
Map<String, Integer> counts = countWords(text);
System.out.println(counts); // {hello=2, world=2, java=2}
}
}

八、性能考虑与最佳实践

  1. 字符串拼接性能

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // 不好 - 创建多个临时对象
    String result = "";
    for (int i = 0; i < 100; i++) {
    result += i;
    }

    // 好 - 使用StringBuilder
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100; i++) {
    sb.append(i);
    }
    String result = sb.toString();
  2. 字符串比较

    1
    2
    3
    4
    5
    6
    7
    8
    // 不好 - 可能NullPointerException
    if (str.equals("literal")) {...}

    // 好 - 避免NPE
    if ("literal".equals(str)) {...}

    // 更好 - Java 7+
    if (Objects.equals(str, "literal")) {...}
  3. 字符串常量池利用

    1
    2
    3
    4
    5
    // 不好 - 创建不必要的对象
    String str = new String("literal");

    // 好 - 利用字符串常量池
    String str = "literal";
  4. 处理大文本

    1
    2
    3
    4
    5
    6
    7
    // 对于大文件处理,避免一次性加载到内存
    try (BufferedReader reader = new BufferedReader(new FileReader("large.txt"))) {
    String line;
    while ((line = reader.readLine()) != null) {
    // 处理每行
    }
    }
  5. 国际化考虑

    1
    2
    3
    // 指定Locale进行大小写转换
    String lower = str.toLowerCase(Locale.ENGLISH);
    String upper = str.toUpperCase(Locale.FRENCH);

通过合理使用 String 类及其相关工具类,可以高效地处理各种文本操作需求。记住字符串是不可变对象,在需要频繁修改字符串的场景中应考虑使用 StringBuilder 或 StringBuffer。

Java StringBuffer 和 StringBuilder 类全面解析

StringBuffer 和 StringBuilder 是 Java 中用于高效处理可变字符串的类。下面我将系统地讲解这两个类的功能、区别和使用场景。

一、StringBuffer 和 StringBuilder 基础

1. 创建对象

1
2
3
4
5
6
7
8
9
// StringBuilder 创建
StringBuilder sb1 = new StringBuilder(); // 默认容量16
StringBuilder sb2 = new StringBuilder(100); // 指定初始容量
StringBuilder sb3 = new StringBuilder("Hello"); // 初始内容

// StringBuffer 创建
StringBuffer sbf1 = new StringBuffer(); // 默认容量16
StringBuffer sbf2 = new StringBuffer(100); // 指定初始容量
StringBuffer sbf3 = new StringBuffer("World"); // 初始内容

2. 主要区别

特性 StringBuilder StringBuffer
线程安全 非线程安全 线程安全
性能 更高 稍低
引入版本 Java 5 Java 1.0
适用场景 单线程环境 多线程环境

二、常用方法详解

1. 追加内容 (append)

1
2
3
4
5
6
7
8
9
10
11
StringBuilder sb = new StringBuilder("Hello");

// 追加各种类型数据
sb.append(" "); // 字符串
sb.append("World"); // 字符串
sb.append(123); // 整数
sb.append(3.14); // 浮点数
sb.append('!'); // 字符
sb.append(true); // 布尔值

System.out.println(sb); // "Hello World1233.14!true"

2. 插入内容 (insert)

1
2
3
4
5
6
7
8
StringBuilder sb = new StringBuilder("HelloWorld");

// 在指定位置插入各种类型数据
sb.insert(5, " "); // 在索引5处插入空格
sb.insert(6, "Java"); // 在索引6处插入"Java"
sb.insert(10, 2023); // 在索引10处插入数字

System.out.println(sb); // "Hello JavaWorld2023"

3. 删除内容 (delete)

1
2
3
4
5
6
7
8
9
StringBuilder sb = new StringBuilder("HelloJavaWorld");

// 删除指定范围的字符
sb.delete(5, 9); // 删除索引5-8的字符("Java")
System.out.println(sb); // "HelloWorld"

// 删除指定位置的字符
sb.deleteCharAt(5); // 删除索引5的字符('W')
System.out.println(sb); // "Helloorld"

4. 替换内容 (replace)

1
2
3
4
5
6
7
8
9
StringBuilder sb = new StringBuilder("HelloWorld");

// 替换指定范围的字符
sb.replace(5, 10, "Java"); // 替换索引5-9的字符
System.out.println(sb); // "HelloJava"

// 设置指定位置的字符
sb.setCharAt(5, 'j'); // 替换索引5的字符
System.out.println(sb); // "Hellojava"

5. 反转字符串 (reverse)

1
2
3
StringBuilder sb = new StringBuilder("Hello");
sb.reverse();
System.out.println(sb); // "olleH"

三、容量管理

1. 容量相关方法

1
2
3
4
5
6
7
8
9
10
11
StringBuilder sb = new StringBuilder(50);  // 初始容量50

// 获取信息
int length = sb.length(); // 当前长度 (0)
int capacity = sb.capacity(); // 当前容量 (50)

// 确保最小容量
sb.ensureCapacity(100); // 确保容量至少100

// 设置长度
sb.setLength(10); // 设置长度为10,可能用null字符填充

2. 容量增长机制

当追加内容超过当前容量时,会自动扩容:

  • 新容量 = (原容量 + 1) * 2
  • 如果还不够,则直接扩容到所需大小
1
2
3
StringBuilder sb = new StringBuilder();  // 默认容量16
sb.append("12345678901234567"); // 长度17
System.out.println(sb.capacity()); // 34 (16+1)*2

四、字符串操作

1. 获取子串和字符

1
2
3
4
5
6
7
8
9
10
11
StringBuilder sb = new StringBuilder("HelloWorld");

// 获取字符
char ch = sb.charAt(4); // 'o'

// 获取子串
String sub1 = sb.substring(5); // "World"
String sub2 = sb.substring(5, 8); // "Wor"

// 获取字符序列
CharSequence seq = sb.subSequence(3, 6); // "loW"

2. 查找操作

1
2
3
4
5
6
7
8
9
StringBuilder sb = new StringBuilder("HelloHello");

// 查找字符串
int first = sb.indexOf("ell"); // 1
int from = sb.indexOf("ell", 2); // 6

// 反向查找
int last = sb.lastIndexOf("ell"); // 6
int lastFrom = sb.lastIndexOf("ell", 5); // 1

五、实际应用示例

1. 高效字符串拼接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class StringConcatenation {
public static String buildString(String[] parts) {
StringBuilder sb = new StringBuilder();
for (String part : parts) {
sb.append(part);
}
return sb.toString();
}

public static void main(String[] args) {
String[] words = {"This", " ", "is", " ", "a", " ", "test"};
System.out.println(buildString(words)); // "This is a test"
}
}

2. SQL 查询构建

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
public class SqlBuilder {
public static String buildQuery(String table, String[] columns, String condition) {
StringBuilder sql = new StringBuilder("SELECT ");

// 添加列
if (columns == null || columns.length == 0) {
sql.append("*");
} else {
for (int i = 0; i < columns.length; i++) {
if (i > 0) sql.append(", ");
sql.append(columns[i]);
}
}

// 添加表名
sql.append(" FROM ").append(table);

// 添加条件
if (condition != null && !condition.isEmpty()) {
sql.append(" WHERE ").append(condition);
}

return sql.toString();
}

public static void main(String[] args) {
String[] cols = {"id", "name", "age"};
String query = buildQuery("users", cols, "age > 18");
System.out.println(query);
// 输出: SELECT id, name, age FROM users WHERE age > 18
}
}

3. CSV 文件生成

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
public class CsvGenerator {
public static String generateCsv(String[] headers, String[][] data) {
StringBuilder csv = new StringBuilder();

// 添加表头
for (int i = 0; i < headers.length; i++) {
if (i > 0) csv.append(",");
csv.append("\"").append(headers[i]).append("\"");
}
csv.append("\n");

// 添加数据行
for (String[] row : data) {
for (int i = 0; i < row.length; i++) {
if (i > 0) csv.append(",");
csv.append("\"").append(row[i]).append("\"");
}
csv.append("\n");
}

return csv.toString();
}

public static void main(String[] args) {
String[] headers = {"Name", "Age", "City"};
String[][] data = {
{"Alice", "25", "New York"},
{"Bob", "30", "London"},
{"Charlie", "22", "Paris"}
};

System.out.println(generateCsv(headers, data));
}
}

六、性能考虑与最佳实践

  1. 选择正确的类

    1
    2
    3
    4
    5
    // 单线程环境 - 使用StringBuilder
    StringBuilder sb = new StringBuilder();

    // 多线程环境 - 使用StringBuffer
    StringBuffer sbf = new StringBuffer();
  2. 初始化容量

    1
    2
    // 如果知道大概大小,预先设置容量
    StringBuilder sb = new StringBuilder(1024); // 避免频繁扩容
  3. 链式调用

    1
    2
    3
    4
    5
    6
    // 使用方法链提高可读性
    String result = new StringBuilder()
    .append("Name: ").append(name)
    .append(", Age: ").append(age)
    .append(", Score: ").append(score)
    .toString();
  4. 与String的转换

    1
    2
    3
    4
    // 只在需要时才转换为String
    StringBuilder sb = new StringBuilder();
    // ...多次操作...
    String finalString = sb.toString(); // 最后转换
  5. 线程安全考虑

    1
    2
    3
    4
    5
    6
    7
    8
    // 在多线程环境中使用StringBuffer
    StringBuffer sharedBuffer = new StringBuffer();

    // 或者使用同步包装
    StringBuilder sb = new StringBuilder();
    synchronized(sb) {
    sb.append("thread-safe operation");
    }
  6. 避免不必要的使用

    1
    2
    3
    4
    5
    6
    7
    8
    // 简单拼接不需要StringBuilder
    String simple = "Hello " + name; // 编译器会自动优化

    // 循环中应该使用StringBuilder
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < 100; i++) {
    sb.append(i);
    }

通过合理使用 StringBuffer 和 StringBuilder,可以显著提高字符串处理性能,特别是在需要频繁修改字符串内容的场景中。根据线程安全需求选择合适的类,并注意容量管理和转换时机,以获得最佳性能。