Java 新版本给 String 加了哪些实用方法?isBlank、strip、repeat、lines、formatted 怎么用?
简化版
**从 Java 11 起,String 陆续新增了一批实用方法,让常见的字符串操作不用再依赖工具类(如 Apache Commons 的 StringUtils)或手写循环。**常用的:① isBlank()——判断字符串「是不是空白」(空串或只有空格/制表符等空白字符),比 isEmpty()(只判断长度 0)更实用;② strip()/stripLeading()/stripTrailing()——去掉首尾空白,比老的 trim() 更好(strip 能正确处理 Unicode 空白字符,trim 只处理 ASCII ≤ 空格的字符);③ repeat(n)——把字符串重复 n 次("ab".repeat(3) → "ababab");④ lines()——按行拆分成 Stream<String>(处理多行文本);⑤ formatted(args)(Java 15)——实例方法版的 String.format("%d".formatted(5));⑥ chars()——转成字符的 IntStream。核心价值:这些方法把「判空白、去空白、重复、按行处理」这些高频操作标准化到 String 上,代码更简洁、少依赖第三方库。
详细版
常用新增 String 方法:
| 方法 | 版本 | 作用 |
|---|---|---|
| isBlank() | 11 | 是否空白(空或只有空白字符) |
| strip()/stripLeading/stripTrailing | 11 | 去首尾空白(Unicode 感知,优于 trim) |
| repeat(n) | 11 | 重复 n 次 |
| lines() | 11 | 按行拆成 Stream |
| formatted(args) | 15 | 实例版 String.format |
| chars() | 8 | 转成字符的 IntStream |
| indent(n) | 12 | 每行缩进 n 个空格 |
// isBlank:判断空白(比 isEmpty 更实用)
" ".isBlank(); // true(只有空格)
"".isBlank(); // true(空串)
" a ".isBlank(); // false
"".isEmpty(); // true(isEmpty 只看长度)
" ".isEmpty(); // false(有空格,长度不为 0)
// strip:去首尾空白(优于 trim)
" hello ".strip(); // "hello"
" hello ".stripLeading(); // "hello "(只去前面)
" hello ".stripTrailing(); // " hello"(只去后面)
// repeat:重复
"=".repeat(20); // "===================="
"ab".repeat(3); // "ababab"
// lines:按行拆成 Stream
"line1\nline2\nline3".lines()
.filter(l -> !l.isBlank())
.forEach(System.out::println);
// formatted:实例版 format
"Hello, %s! You are %d.".formatted("Tom", 18); // "Hello, Tom! You are 18."
⚠️
strip()和trim()的区别是个高频细节:两者都去首尾空白,但trim()是「老古董」,只去掉 ASCII 码 ≤ 空格(0x20)的字符,对 Unicode 的空白字符(如全角空格、某些 Unicode 空白)处理不了;而strip()(Java 11)是「Unicode 感知」的,用Character.isWhitespace()判断,能正确去掉各种 Unicode 空白字符。所以新代码优先用strip(),尤其处理可能含全角空格、多语言文本时。同理,判断字符串「有没有实际内容」优先用isBlank()(空或全空白都算「空」)而非isEmpty()(只判断长度为 0," "不算 empty)——isBlank()更符合「这个字符串有没有有效内容」的直觉。
完整版教学
一、背景:减少对工具类的依赖
先理解这些新方法的价值:
过去做常见字符串操作,要么手写、要么依赖工具类:
判断空白:StringUtils.isBlank(s)(Apache Commons)或手写
去首尾空白:s.trim()(但处理不了 Unicode 空白)
重复字符串:手写循环 或 StringUtils.repeat
按行处理:s.split("\n") 或 BufferedReader.lines
问题:
① 依赖第三方库(Apache Commons Lang 等)为了几个方法
② 手写循环繁琐易错
③ trim 有 Unicode 缺陷
Java 11+ 的改进:
把这些高频操作直接加到 String 上(标准库自带)
isBlank/strip/repeat/lines/formatted...
→ 不用依赖第三方库、不用手写、更标准
所以这些新方法的价值:
把常见字符串操作"内置化、标准化",代码更简洁、少依赖
这些新方法的背景是「减少对工具类的依赖、标准化常见操作」——过去判空白/去空白/重复/按行处理要依赖 Apache Commons 或手写循环(依赖第三方库、繁琐、trim 有 Unicode 缺陷)。Java 11+ 把这些高频操作直接加到 String 上(标准库自带、不用依赖第三方、更标准)。理解「新 String 方法减少对工具类依赖、把判空白/去空白/重复/按行处理等高频操作内置标准化、代码更简洁少依赖」,就理解了它们的价值。
二、isBlank:判断空白
isBlank() 判断「有没有实际内容」,比 isEmpty() 实用:
isBlank()(Java 11):
字符串是"空"或"只包含空白字符"(空格、制表符、换行等)→ true
"".isBlank() → true(空串)
" ".isBlank() → true(只有空格)
"\t\n".isBlank() → true(只有空白字符)
" a ".isBlank() → false(有实际内容 a)
对比 isEmpty():
isEmpty():长度是否为 0
"".isEmpty() → true
" ".isEmpty() → false(有 3 个空格,长度不为 0)
区别:
isEmpty:只看"长度是不是 0"
isBlank:看"有没有实际(非空白)内容"
什么时候用哪个:
判断"有没有输入实际内容"(如表单校验)→ isBlank(更符合直觉)
纯粹判断"长度是不是 0" → isEmpty
isBlank 底层:用 strip 后是否为空判断(Unicode 感知的空白)
isBlank()(Java 11)判断「空或只包含空白字符」→ true(""、" "、"\t\n" 都是 blank)。对比 isEmpty() 只看长度是否为 0(" " 有 3 个空格、长度不为 0、不 empty)。区别:isEmpty 看长度是不是 0、isBlank 看有没有实际(非空白)内容。判断「有没有输入实际内容」(表单校验)用 isBlank(更符合直觉)。理解「isBlank 判断空或只有空白字符、isEmpty 只看长度是否为 0(空格不算空)、判断有没有实际内容用 isBlank」,就掌握了 isBlank。
三、strip:去空白(优于 trim)
strip() 去首尾空白,比 trim() 好:
strip()(Java 11):去掉首尾的空白字符
stripLeading():只去前面
stripTrailing():只去后面
" hello ".strip() → "hello"
" hello ".stripLeading() → "hello "
" hello ".stripTrailing() → " hello"
★ strip vs trim(高频区别):
trim()(老方法):
只去掉 ASCII 码 ≤ 0x20(空格)的字符
→ 处理不了 Unicode 空白(如全角空格 )
"全角空格 hello".trim() → 全角空格没去掉(trim 不认识它)
strip()(Java 11):
用 Character.isWhitespace() 判断,Unicode 感知
→ 能正确去掉各种 Unicode 空白字符
"全角空格 hello".strip() → 正确去掉
所以:
新代码优先用 strip(正确处理 Unicode 空白)
尤其处理多语言/可能含全角空格的文本
trim 是历史遗留,有 Unicode 缺陷
strip()(Java 11)去首尾空白(stripLeading 只去前、stripTrailing 只去后)。strip vs trim(高频区别):trim() 只去 ASCII ≤ 0x20 的字符(处理不了 Unicode 空白如全角空格 );strip() 是 Unicode 感知的(用 Character.isWhitespace(),能去各种 Unicode 空白)。新代码优先用 strip(正确处理 Unicode 空白,尤其多语言/含全角空格的文本),trim 是历史遗留有缺陷。理解「strip 去首尾空白(Leading/Trailing 只去一边)、strip vs trim:trim 只去 ASCII≤空格处理不了 Unicode 空白(全角空格)、strip Unicode 感知、新代码优先 strip」,就掌握了 strip。
四、repeat 与 lines
repeat 和 lines 处理重复和多行:
repeat(n)(Java 11):把字符串重复 n 次
"=".repeat(20) → "===================="(画分隔线)
"ab".repeat(3) → "ababab"
"x".repeat(0) → ""(0 次是空串)
→ 替代手写循环拼接、StringBuilder 循环 append
实用场景:画分隔线、生成缩进、填充占位
lines()(Java 11):按行拆分成 Stream<String>
"a\nb\nc".lines() → Stream["a", "b", "c"]
→ 按行终止符(\n、\r\n、\r)拆分
→ 返回 Stream,可以链式处理每一行
例:处理多行文本
text.lines()
.filter(line -> !line.isBlank()) // 过滤空行
.map(String::strip) // 每行去空白
.forEach(System.out::println)
对比 split("\n"):
lines() 返回 Stream(可链式)、正确处理各种行终止符、更高效
split("\n") 返回数组、要自己处理 \r\n
→ 按行处理优先用 lines()
repeat(n)(Java 11)重复字符串 n 次("=".repeat(20) 画分隔线、"ab".repeat(3)→"ababab",替代手写循环拼接)。lines()(Java 11)按行拆成 Stream<String>(按行终止符拆分、返回 Stream 可链式处理,text.lines().filter(...).map(...) 处理多行文本)。lines vs split(“\n”):lines() 返回 Stream 可链式、正确处理各种行终止符(\n/\r\n/\r)、更高效;split 返回数组要自己处理 \r\n——按行处理优先用 lines()。理解「repeat(n)重复 n 次(画分隔线/替代循环拼接)、lines()按行拆成 Stream 可链式(优于 split(‘\n’)处理各种行终止符更高效)」,就掌握了 repeat 和 lines。
五、formatted 与其他
formatted 和其他实用方法:
formatted(args)(Java 15):实例版的 String.format
"Hello, %s! Age %d".formatted("Tom", 18)
→ "Hello, Tom! Age 18"
→ 等价于 String.format("Hello, %s! Age %d", "Tom", 18)
→ 但链式更自然(模板在前、参数在后)
常配合文本块(Text Blocks)用:
"""
Name: %s
Age: %d
""".formatted(name, age)
chars()(Java 8):把字符串转成字符的 IntStream
"hello".chars() → IntStream of [104, 101, 108, 108, 111](char 的 int 值)
→ 可以统计、过滤字符
"hello".chars().filter(c -> c == 'l').count() // 统计 'l' 的个数
indent(n)(Java 12):每行缩进 n 个空格
"line1\nline2".indent(4) → 每行前加 4 个空格
transform(fn)(Java 12):对字符串应用一个函数(函数式链式)
"hello".transform(String::toUpperCase) → "HELLO"
其他:
stripIndent()(Java 15):去掉多行文本的公共缩进(文本块用)
translateEscapes():处理转义序列
其他实用方法:formatted(args)(Java 15)——实例版 String.format("...%s...".formatted(x),链式更自然,常配合文本块);chars()(Java 8)——转成字符的 IntStream(统计/过滤字符);indent(n)(Java 12)——每行缩进 n 个空格;transform(fn)(Java 12)——对字符串应用函数(函数式链式);stripIndent(去多行公共缩进,文本块用)。理解「formatted 实例版 String.format(配合文本块)、chars 转字符 IntStream(统计过滤字符)、indent 每行缩进、transform 应用函数链式」,就掌握了其他方法。
六、实践小结
总结这些新方法的实践:
高频操作用哪个方法:
判断有没有实际内容 → isBlank()(不是 isEmpty)
去首尾空白 → strip()(不是 trim,Unicode 感知)
重复字符串 → repeat(n)(不是手写循环)
按行处理 → lines()(不是 split("\n"))
格式化 → formatted()(配合文本块)
统计/过滤字符 → chars()
选择原则(新 vs 老):
isBlank 优于 isEmpty(判断实际内容)
strip 优于 trim(Unicode 感知)
lines 优于 split("\n")(Stream + 正确处理行终止符)
repeat 优于手写循环
减少依赖:
很多以前要用 Apache Commons StringUtils 的操作,
现在标准库 String 自带 → 可以减少对第三方库的依赖
一句话:
Java 11+ 的 String 新方法把高频操作标准化了,
新代码优先用它们(isBlank/strip/repeat/lines/formatted),
比老方法(isEmpty/trim/split/手写)更好、更标准
这些新方法的实践:判断实际内容用 isBlank(不是 isEmpty)、去空白用 strip(不是 trim,Unicode 感知)、重复用 repeat(不是手写循环)、按行用 lines(不是 split)、格式化用 formatted(配文本块)、统计字符用 chars。选择原则「新优于老」(isBlank>isEmpty、strip>trim、lines>split、repeat>手写)。还能减少对 Apache Commons StringUtils 的依赖。理解「实践:判断内容用 isBlank、去空白用 strip、重复用 repeat、按行用 lines、格式化用 formatted;新优于老;减少对第三方库依赖」,就掌握了这些方法的实践。
记忆钩子:「Java 11+ String 新方法:①isBlank()判断空或只有空白字符(比 isEmpty 只看长度更实用,’ ‘是 blank 但不 empty)②strip()/stripLeading/stripTrailing 去首尾空白★优于 trim(trim 只去 ASCII≤空格处理不了 Unicode 空白如全角空格,strip 用 Character.isWhitespace Unicode 感知)③repeat(n)重复 n 次(画分隔线/替代循环拼接)④lines()按行拆成 Stream(优于 split(‘\n’)处理各种行终止符更高效可链式)⑤formatted(args)实例版 String.format(配合文本块)⑥chars()转字符 IntStream;新优于老:isBlank>isEmpty、strip>trim、lines>split;减少对 Apache Commons StringUtils 依赖」。
七、常见误区与追问
- 误区:判断字符串为空用 isEmpty 就够了。 isEmpty 只看长度是否为 0——” “(有空格)不算 empty;判断「有没有实际内容」应该用 isBlank(空或只有空白字符都算 blank),更符合「这个字符串有没有有效内容」的直觉,尤其表单校验。
- 误区:strip 和 trim 完全一样。 都去首尾空白,但 trim 只去 ASCII ≤ 0x20(空格)的字符、处理不了 Unicode 空白(如全角空格 );strip(Java 11)用 Character.isWhitespace() 判断、Unicode 感知、能正确去各种 Unicode 空白;新代码优先用 strip。
- 误区:重复字符串要手写循环拼接。 用 repeat(n)——”=“.repeat(20) 直接得到 20 个等号,替代手写 for 循环 StringBuilder append;更简洁、意图清晰;repeat(0) 返回空串。
- 误区:按行处理用 split(“\n”) 最好。 lines() 更好——它返回 Stream
(可链式 filter/map)、正确处理各种行终止符(\n、\r\n、\r),而 split(“\n”) 返回数组、要自己处理 \r\n 的残留 \r;按行处理优先用 lines()。 - 追问:isBlank 和 isEmpty 有什么区别? isEmpty() 判断字符串长度是否为 0("" 是 true,” ” 是 false,因为有空格长度不为 0);isBlank() 判断字符串是空或只包含空白字符(""、” ”、“\t\n” 都是 true);判断「有没有实际内容」用 isBlank 更合适。
- 追问:为什么推荐 strip 而不是 trim? trim 是老方法,只去掉 ASCII 码 ≤ 0x20(空格)的字符,对 Unicode 的空白字符(全角空格 、其他 Unicode 空白)无能为力;strip(Java 11)用 Character.isWhitespace() 判断,是 Unicode 感知的,能正确去掉各种 Unicode 空白字符;处理多语言文本、可能含全角空格时 strip 才正确。
- 追问:lines() 相比 split(“\n”) 有什么优势? lines() 返回 Stream
(可以直接链式 filter/map/forEach 处理每一行),并且正确识别各种行终止符(\n、\r\n、\r);split(“\n”) 返回 String[] 数组、遇到 \r\n 会残留 \r 在每行末尾、要自己处理;lines() 更简洁、更正确、更高效(惰性 Stream)。
八、加强记忆
从 Java 11 起,String 新增了一批实用方法,把高频字符串操作标准化到标准库(减少对 Apache Commons StringUtils 的依赖)。常用:① isBlank()(Java 11)——判断「空或只包含空白字符」(比 isEmpty() 只看长度更实用," " 是 blank 但不 empty,判断「有没有实际内容」用它);② strip()/stripLeading()/stripTrailing()(Java 11)——去首尾空白,优于 trim()(trim 只去 ASCII ≤ 空格、处理不了 Unicode 空白如全角空格;strip 用 Character.isWhitespace()、Unicode 感知、新代码优先用);③ repeat(n)(Java 11)——重复 n 次(画分隔线、替代循环拼接);④ lines()(Java 11)——按行拆成 Stream<String>(优于 split("\n"),正确处理各种行终止符、返回 Stream 可链式、更高效);⑤ formatted(args)(Java 15)——实例版 String.format(配合文本块);⑥ chars()(Java 8)——转成字符的 IntStream(统计/过滤字符);还有 indent/transform/stripIndent 等。选择原则「新优于老」:isBlank>isEmpty、strip>trim、lines>split、repeat>手写循环。一句话「Java 11+ String 新方法:isBlank(空或全空白,比 isEmpty 实用)、strip(去首尾空白,Unicode 感知优于 trim)、repeat(n)(重复)、lines(按行拆 Stream 优于 split)、formatted(实例版 format 配文本块)、chars(转字符 IntStream);新优于老,减少对第三方库依赖」。