方法定义
public synchronized void setLength(int newLength)
- 参数:
newLength
- 新的字符序列长度(必须 ≥ 0) - 异常:
IndexOutOfBoundsException
:如果newLength < 0
- 线程安全:使用
synchronized
修饰(多线程安全)
功能说明
设置字符序列的新长度,主要实现两种功能:
- 扩展长度:用空字符(
\u0000
)填充新增位置 - 截断长度:丢弃超出
newLength
的字符 - 缓冲区复用:重置长度而不新建对象
示例代码
// 示例1:扩展长度
StringBuffer sb = new StringBuffer("Hello");
sb.setLength(8); // 扩展长度
System.out.println(sb); // 输出 "Hello "(末尾3个空字符)
System.out.println((int)sb.charAt(6)); // 输出 0(空字符的ASCII值)
// 示例2:截断字符串
sb.setLength(3); // 截断
System.out.println(sb); // 输出 "Hel"
// 示例3:清空缓冲区
sb.setLength(0); // 清空
System.out.println("|" + sb + "|"); // 输出 "||"(空字符串)
使用技巧
- 快速清空缓冲区(替代
new StringBuffer()
):StringBuffer buffer = new StringBuffer(); // 重复使用 buffer.append("Data"); buffer.setLength(0); // 清空内容,保留底层数组
- 填充固定长度字符串:
StringBuffer sb = new StringBuffer(); sb.setLength(5); // 预先分配5个空字符 sb.replace(0, 5, "12345"); // 快速填充
常见错误
- 负长度设置:
sb.setLength(-1); // 抛出 IndexOutOfBoundsException
- 误解缓冲区容量:
StringBuffer sb = new StringBuffer(100); // 容量=100 sb.setLength(50); // 设置的是长度,容量仍为100 System.out.println(sb.capacity()); // 输出 100
注意事项
- 空字符填充:扩展时新增位置用
\u0000
填充- 打印时显示为空格,但实际是不同字符
- 不可逆操作:截断后数据永久丢失
sb.append("Important Data"); sb.setLength(5); // 数据被永久截断
- 长度 vs 容量:
length()
:当前存储的字符数capacity()
:当前分配的存储空间大小
性能优化
- 对象复用:在循环中重用缓冲区
StringBuffer sb = new StringBuffer(); for (int i = 0; i < 1000; i++) { sb.append("data"); process(sb); sb.setLength(0); // 比 new StringBuffer() 高效90% }
- 避免过度扩展:合理设置初始容量
// 预估最大长度500 StringBuffer sb = new StringBuffer(500);
总结
核心功能 | 关键点 |
---|---|
长度扩展 | 新增位置用空字符(\u0000 )填充 |
长度截断 | 永久丢弃超出部分的字符 |
缓冲区复用 | setLength(0) 比新建对象快10倍(避免内存分配和GC) |
线程安全 | 多线程操作首选 StringBuffer ,单线程用 StringBuilder 更高效 |
容量管理 | setLength() 只改长度,不改容量;用 ensureCapacity() 管理空间 |
最佳实践:
- 循环操作必用:
setLength(0)
复用缓冲区// 高效模板 StringBuffer reusable = new StringBuffer(); while (condition) { reusable.append(...); process(reusable); reusable.setLength(0); // 关键! }
- 安全截断:先检查再截断
if (newLength <= sb.length()) { sb.setLength(newLength); }
- 长度校正:处理外部输入时验证长度
int userInputLength = getUserInput(); if (userInputLength >= 0) { sb.setLength(userInputLength); }
⚠️ 关键警告:
截断操作不可逆!确保不再需要被丢弃的数据。
扩展时空字符可能影响字符串比较(equals()
和\u0000
不匹配)。