跳到内容

元数据卡

  • 前置知识:字符串基础(上一页)
  • 预计时间:15 分钟
  • 完成标志:能正确分割、替换字符串,知道什么场景用 StringBuilder

你的进度

你知道 String 不可变了。那日常怎么拆字符串、拼字符串、替换文本?遇到大量拼接时,为什么必须扔掉 + 号换成 StringBuilder?这一页不问了,直接上手。


substring —— 截取子串

java
String url = "https://example.com/api/users";
String domain = url.substring(8, 23);   // [8, 23)
String path = url.substring(23);

System.out.println(domain);
System.out.println(path);

运行步骤: 索引从 0 数:h(0) t(1) ... e(8) ... substring(8, 23) 取含 8 不含 23 的字符。

预期输出:

example.com
/api/users

split —— 分割字符串(经典坑)

java
String ip = "192.168.1.1";
String[] parts = ip.split(".");          // 参数是正则!
System.out.println(Arrays.toString(parts));

String[] parts2 = ip.split("\\.");       // 正确写法
System.out.println(Arrays.toString(parts2));

运行步骤: "." 在正则里匹配任意字符(不是字面点号),整个串被匹配光,返回空数组。

预期输出:

[]
[192, 168, 1, 1]

面试高频题,也是线上出 Bug 最多的 split 坑。记住:特殊字符要转义。


trim 和 strip —— 去除空白

java
String padded = "  \u2003Hello\u2003  ";  // \u2003 是全角空格
System.out.println("'" + padded.trim() + "'");
System.out.println("'" + padded.strip() + "'");  // Java 11+

预期输出:

'   Hello  '      (trim 没去干净)
'Hello'            (strip 去了)

Java 11 以上优先用 strip()。


replace 和 replaceAll

java
String text = "I like cats. Cats are cute.";
String r1 = text.replace("cats", "dogs");           // 字面量替换
String r2 = text.replaceAll("\\b[Cc]ats\\b", "dogs"); // 正则替换
System.out.println(r1);
System.out.println(r2);

预期输出:

I like dogs. Cats are cute.
I like dogs. dogs are cute.

replace() 是字面量,replaceAll / replaceFirst 是正则。


StringBuilder vs StringBuffer

java
// 循环用 += 拼接 —— 每次等价于 new StringBuilder().append()...toString()
String result = "";
for (int i = 0; i < 100_000; i++) {
    result += "line " + i + "\n";
}
// 10 万次 = 10 万个临时对象,GC 暴走

// 正确做法
StringBuilder sb = new StringBuilder(1_000_000);   // 预分配容量
for (int i = 0; i < 100_000; i++) {
    sb.append("line ").append(i).append("\n");
}
String result2 = sb.toString();
特性StringBuilderStringBuffer
线程安全不安全同步
性能最快慢 2-3 倍
适用单线程拼接(99% 场景)多线程共享缓冲区

选择原则:除非明确多线程共享,永远用 StringBuilder。


常用方法速查

方法作用注意
length()字符串长度不是属性,是方法
charAt(i)取第 i 个字符越界抛异常
substring(b, e)截取终点不含
indexOf(ch)查找位置-1 找不到
contains(s)是否含子串内部调 indexOf
split(regex)按正则分割参数是正则
replace(a, b)字面替换不是正则
replaceAll(re, s)正则替换全部参数是正则
trim()去 ASCII 空格不处理 Unicode
strip()去所有空白Java 11+ 推荐
join(delim, parts)合并静态方法
java
String[] fruits = {"apple", "banana", "orange"};
String joined = String.join(", ", fruits);
System.out.println(joined);

预期输出:

apple, banana, orange
java
String result = "  Hello World  ".strip().substring(0, 5).toUpperCase();
System.out.println(result);

运行步骤: strip → "Hello World" → substring(0, 5) → "Hello" → toUpperCase → "HELLO"

预期输出:

HELLO

旅人笔记

split 的参数是正则,特殊字符要转义。大量拼接用 StringBuilder + 预分配容量。strip() 比 trim() 更彻底。replace 是字面量,replaceAll 是正则。

-> 下一步:核心集合

字符串搞定了。但要存几十个"hello"、按名字查人、保证不重复——你需要集合框架了。

看集合框架 ->

Built with VitePress | Software Systems Atlas