字符串小记
String 与 StringBuilder 的比较
在 Java 中,String
和 StringBuilder
都是用于处理字符串的类,但它们在不可变性、性能、和适用场景等方面存在显著区别。
1. 不可变性
- String:不可变对象(immutable),一旦创建了字符串对象,内容就不能再改变。每次对
String
执行修改操作(如拼接、替换等)时,都会生成一个新的String
对象。 - StringBuilder:可变对象(mutable),允许对字符串内容进行修改,能够在原对象的基础上进行拼接、删除等操作。
2. 性能
- String:由于每次修改字符串都会创建新对象,所以在多次拼接或修改字符串时会产生大量临时对象,导致性能下降,尤其在循环中频繁修改字符串时,效率低下。
- StringBuilder:
StringBuilder
允许在原对象基础上修改字符串,避免了创建多个临时对象,内存和速度效率都更高,特别适合在循环中对字符串进行频繁修改的场景。
3. 线程安全性
- String:是不可变的,因此是线程安全的,可以在多个线程中安全地使用。
- StringBuilder:是可变的,但不保证线程安全。如果在多线程环境中需要安全地修改字符串内容,应使用
StringBuffer
(另一种线程安全的可变字符串类)代替StringBuilder
。
4. 使用场景
- String:适合不需要修改的字符串内容,比如静态文本、常量字符串、少量拼接操作。
- StringBuilder:适合需要频繁拼接、修改字符串内容的场景,比如构建动态 SQL 语句、大量文本处理、或在循环中拼接字符串等。
5. 示例代码
-
String 拼接示例(会创建多个临时对象,性能较差):
1
2
3
4
5String result = "Hello";
for (int i = 0; i < 5; i++) {
result += " World"; // 每次都会创建新的 String 对象
}
System.out.println(result); // 输出:Hello World World World World World -
StringBuilder
拼接示例(在原对象基础上修改,性能更高):1
2
3
4
5StringBuilder sb = new StringBuilder("Hello");
for (int i = 0; i < 5; i++) {
sb.append(" World"); // 修改原对象,不创建新对象
}
System.out.println(sb.toString()); // 输出:Hello World World World World World
总结
特性 | String |
StringBuilder |
---|---|---|
是否可变 | 不可变 | 可变 |
性能 | 修改操作较慢 | 修改操作较快 |
线程安全性 | 线程安全 | 非线程安全 |
适用场景 | 少量或不可变字符串操作 | 频繁拼接、修改字符串的操作 |
结论:当需要对字符串进行大量修改操作时,使用 StringBuilder
会显著提高性能。对于静态文本或少量操作,使用 String
更为合适。
字符串练习题解析
第一题解析
代码:
1 | public class Test { |
选项解析:
s1 == s2
:结果为true
,因为s1
和s2
都指向字符串常量池中的"java"
字符串,指向相同的内存地址。s3 == s4
:结果为false
,因为s3
是通过new String("java")
创建的对象,s4
是通过new StringBuilder("java").toString()
创建的对象,二者是不同的实例,指向不同的内存地址。s1.equals(s4)
:结果为true
,因为equals
方法比较的是字符串内容,s1
和s4
的内容都是"java"
。
正确答案:B. true,false,true
第二题解析
代码:
1 | public class Test { |
选项解析:
s1.substring(1, 3)
:substring
方法提取字符串s1
从索引1
到索引3
(不包括3
)的子字符串。- 索引
1
对应字符'e'
,索引2
对应字符'l'
,因此s1.substring(1, 3)
返回"el"
。
- 索引
正确答案:C. el
第三题解析
代码:
1 | public class Test { |
选项解析:
- 这道题问的是,
s1
所引用的字符串对象内容是否会被修改为"java123"
。 - 答案为“错误”,因为
String
是不可变对象(immutable)。执行s1 += "123";
实际上相当于s1 = s1 + "123";
,会创建一个新的字符串对象"java123"
,并将s1
重新指向这个新对象,而原来的"java"
字符串对象并没有被修改。 - 因此,
s1
引用的字符串对象内容并未被修改,而是指向了一个新的对象。
正确答案:错误
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 WinstonChen's Homepage!
评论