Java面试题:String 和 StringBuilder、StringBuffer的区别??
这三个类的主要区别在两个方面:运算速度(运算性能或执行效率)和线程安全性。
1、运算速度比较(通常情况下):StringBuilder > StringBuffer > String
String是final类不能被继承且为字符串常量,而StringBuilder和StringBuffer均为字符串变量。String对象一旦创建便不可更改,而后两者是可更改的,它们只能通过构造函数来建立对象,且对象被建立以后将在内存中分配内存空间,并初始保存一个null,通过append方法向StringBuffer和StringBuilder中赋值。请看如下示例代码:
String str = "abc";
System.out.println(str);
str = str + "de";
System.out.println(str);
上述代码先创建一个String对象str,并赋值abc给str,然后运行到第三行,JVM会再创建一个新的str对象,并将原有str的值和de加起来再赋值给新的str。而第一个创建的str对象被JVM的垃圾回收机制(GC)回收掉。所以str实际上并没有被更改,即String对象一旦创建就不可更改。所以Java中对String对象进行的操作实际上是一个不断创建并回收对象的过程,因此在运行速度上很慢。
而StringBuilder和StringBuffer的对象是变量,对变量的操作是直接对该对象就行更改,因此不会进行反复的创建和回收。所以在运行速度上比较快。
String str = "abc" + "de";
StringBuilder stringBuilder = new StringBuilder().append("abc").append("de");
System.out.println(str);
System.out.println(stringBuilder.toString());
上述代码中String的操作速度反而要比StringBuilder快,这是因为在JVM眼里,第1行的代码操作和下列代码是完全一样的,所以很快。
String str = "abcde";
但如下的代码写法形式速度会很慢,JVM会不断地创建和回收对象来进行操作。
String str1 = "abc";
String str2 = "de";
String str = str1 + str2;
2. 线程安全性
StringBuilder(非线程安全)
而StringBuilder的方法没有该关键字修饰,所以不能保证线程安全性。是JDK1.5新增的,该类提供一个与StringBuffer兼容的 API,但不能保证同步,所以在性能上较高。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。
StringBuffer(线程安全的)
StringBuffer中大部分方法由synchronized关键字修饰,在必要时可对方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致,所以是线程安全的。类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
3. 总结
String:适用于少量的字符串操作。
StringBuilder:适用于单线程下在字符串缓冲区进行大量操作。
StringBuffer:适用于多线程下在字符串缓冲区进行大量操作。
可参考原文链接:
https://blog.csdn.net/weixin_41101173/article/details/79677982
https://blog.csdn.net/qushaming/article/details/82971901