- 使用
StringBuilder
类:
- 在Java中,
String
对象是不可变的,每次对String
进行拼接操作都会产生一个新的String
对象,这在频繁拼接时会导致大量的内存开销。而StringBuilder
类是可变的,适合用于字符串拼接。
- 原理:
StringBuilder
内部维护一个字符数组,通过append
方法将字符串添加到数组中,最后通过toString
方法生成最终的String
对象。这样在拼接过程中不会频繁创建新的String
对象,从而优化内存使用。
- 示例代码:
public class StringConcatenationOptimization {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
String prefix = "Hello, ";
String name = "John";
for (int i = 0; i < 10; i++) {
sb.append(prefix).append(name).append(i).append("\n");
}
String result = sb.toString();
System.out.println(result);
}
}
- 关于字符串常量池:
- 当使用
+
运算符拼接字符串常量时,Java编译器会在编译期将其优化为一个常量。例如String s = "Hello" + " World";
,在编译后实际等同于String s = "Hello World";
,这个结果字符串会放入字符串常量池中。
- 但是当有变量参与拼接时,
+
运算符会在运行期创建新的String
对象。例如String prefix = "Hello, "; String name = "John"; String s = prefix + name;
,此时s
不会直接放入字符串常量池。而通过StringBuilder
进行拼接并调用toString
后得到的String
对象,如果调用intern
方法,会尝试将其放入字符串常量池。如果常量池中已存在相同内容的字符串,则返回常量池中的引用,否则将当前字符串放入常量池并返回引用。
- 示例代码:
public class StringInternExample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
String prefix = "Hello, ";
String name = "John";
sb.append(prefix).append(name);
String result = sb.toString();
String internedResult = result.intern();
String existingInPool = "Hello, John";
System.out.println(result == existingInPool); // false
System.out.println(internedResult == existingInPool); // true
}
}
- 总结来说,先使用
StringBuilder
进行高效拼接,然后根据需要调用intern
方法利用字符串常量池来进一步优化内存(如果有多个相同内容的字符串可以复用常量池中的对象)。