在Java复杂文本解析中,StringBuilder本身不提供游标API,而是作为可变、高效、带索引的字符容器,配合手动int游标变量实现低开销片段提取;初始化时append原始文本并保持只读,避免扩容干扰索引。

在 Java 复杂文本解析中,用 StringBuilder 维护游标截取片段,核心不是靠它“直接支持游标”,而是把它当作**可变、高效、带索引的字符容器**,配合手动游标变量(如 int pos)来实现低开销的片段提取。
用 int 游标代替 substring() 频繁创建新字符串
StringBuilder 本身不提供游标 API,但你可以用一个整型变量(比如 cursor)记录当前解析位置。每次提取子串时,不再调用 str.substring(start, end)(会生成新 String 对象),而是用 sb.substring(cursor, cursor + len) 或直接操作 sb.charAt() 判断边界——前提是 sb 内容稳定、不频繁修改。
- 初始化时把原始文本 append 进
StringBuilder,后续只读不改,避免扩容干扰索引 - 游标
cursor从 0 开始,每处理完一段就递增,比如跳过空格:while (cursor - 要截取字段时,直接用
sb.substring(cursor, endPos),比反复切原始字符串快,且复用同一底层 char 数组
结合 indexOf / lastIndexOf 定位关键锚点
复杂文本常有分隔符(如 "|"、"\n"、"<tag>"),用 StringBuilder.indexOf(String, fromIndex) 比遍历 char 更快定位。游标作为 fromIndex 起点,能精准圈出目标片段范围。
- 例如解析 CSV 行:
int comma = sb.indexOf(",", cursor);得到下一个字段结束位置 - 字段内容就是
sb.substring(cursor, comma),然后更新cursor = comma + 1 - 若需跳过引号包裹的逗号,可先用
sb.indexOf("\"", cursor)找引号起始,再找匹配闭合引号,中间忽略所有分隔符
必要时用 delete(0, cursor) 释放已处理内存
如果文本极长、解析是流式且不回溯,已解析部分可主动清理:调用 sb.delete(0, cursor) 把前面内容删掉,让 cursor 归零,后续索引更简洁。这比保留全部文本更省内存,尤其适合日志行逐行解析。
立即学习“Java免费学习笔记(深入)”;
- 注意:delete 后原游标值失效,必须重置
cursor = 0 - 仅在确认前段完全无用时使用;若需回溯(如语法错误要重试),禁用此操作
- 配合
sb.ensureCapacity()预分配足够空间,减少扩容次数
避免常见陷阱:线程安全与 toString() 副作用
StringBuilder 非线程安全,多线程解析必须每个线程独占实例;另外,频繁调用 toString() 会生成新 String,抵消性能优势——只在真正需要字符串结果时才调用。
- 不要写
if (sb.toString().startsWith("KEY=")),改用sb.charAt(0)=='K' && sb.charAt(1)=='E'...或sb.indexOf("KEY=", 0) == 0 - 字段校验尽量用
sb.charAt()、sb.codePointAt()直接查码点,避开构造临时字符串 - 解析完成后再批量
toString()输出,或直接用sb构造最终对象(如传给new JsonParser(sb))


















