String.repeat 是底层优化的原子操作,通过预分配内存和批量复制实现高效字符串填充,比 StringBuilder 循环快 15%–30%,比 str += 拼接快百倍以上。

String.repeat 是现代语言中处理字符串填充最直接高效的方式。它不是简单语法糖,而是底层经过内存预分配和批量复制优化的原子操作,能显著避开循环拼接带来的多次内存分配开销。
为什么 repeat 比手动循环快
重复一个字符 10 万次时:
-
String.repeat("x", 100000):仅一次内存分配,底层用数组填充(如
Arrays.fill或Unsafe.copyMemory),耗时通常在微秒级 - StringBuilder 循环 append:虽只分配一次容量,但每次 append 仍需边界检查、长度更新、数组索引维护,实测慢 15%–30%
- str += "x":每次触发新字符串创建 + 原内容拷贝,10 万次即 10 万次内存分配,极易触发 GC,性能下降百倍以上
填充场景中的典型用法
补齐、对齐、占位等需求,核心是算清“补多少”,再用 repeat 生成填充段:
-
左补齐到 12 位(用 '0'):
"0".repeat(Math.max(0, 12 - s.length())) + s -
右补齐到 20 字符(用空格):
s + " ".repeat(Math.max(0, 20 - s.length())) -
生成固定宽度进度条:
"█".repeat(loaded) + "░".repeat(total - loaded),无需 StringBuilder 或数组拼接
使用时必须注意的边界
repeat 方法看似简单,但参数不合规会立刻中断执行:
- 传负数 → 抛
IllegalArgumentException(Java)或RangeError(JS) - 传小数 → JS 中自动取整(
"a".repeat(2.9) === "aa"),Java 要求 int 类型,编译不通过 - 原字符串为 null → 直接
NullPointerException,务必先判空 - 结果超内存限制(如
"a".repeat(Integer.MAX_VALUE))→ 可能 OOM 或 panic,生产环境建议加长度上限校验
对比其他填充方式的实际效果
同是补零到 8 位,不同写法在可读性与运行效率上差异明显:
-
String.format("%08d", num):适合数字格式化,但仅限基本类型;若 num 是字符串则需先转 int,有风险 -
StringUtils.leftPad(str, 8, '0')(Apache Commons):功能强,但引入额外依赖,启动和调用均有开销 -
"0".repeat(8 - str.length()) + str:无依赖、语义清晰、JVM/JIT 易内联,日常填充首选










