目录
简单介绍
String
字符串常量,字符串长度不可变
用于存放值的value[ ]是final类型,因此只能被赋值一次,不能被更改。
StringBuffer
StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。
StringBuilder
StringBuilder:字符串变量(非线程安全)。在内部,StringBuilder 对象被当作是一个包含字符序列的变长数组。
java.lang.StringBuilder 是一个可变的字符序列,是 JDK5.0 新增的。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。
三者区别
三者的主要区别体现在线程安全和改变数据的运行速度上。
运行速度
StringBuilder > StringBuffer > String
String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,然后将指针指向新的 String 对象,而StringBuilder和StringBuffer都是可变的所以改变数据会更快。因为StringBuilder和StringBuffer都没有重写他们的hashcode方法,所以这里直接用hashcode方法获取他们的地址。
public static void main(String[] args) {
StringBuffer s2 = new StringBuffer("s2");
StringBuilder s3 =new StringBuilder("s3");
System.out.println("s2的地址:"+s2.hashCode());
System.out.println("s3的地址:"+s3.hashCode());
s2.append(2);
s3.append(2);
System.out.println("s2的地址:"+s2.hashCode());
System.out.println("s3的地址:"+s3.hashCode());
}
运行结果
可以看出s2和s3对象都没有发生改变。
有特殊情况,看下面的代码
String str="abc"+"de";
StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
他们最终的结果是一样的,但是在这段代码中str的运算速度是最快的。这是因为,String str="abc"+"de" 其实和str="abcde"是一样的,在编译时会自动进行转化,所以更快速。
而 StringBuilder > StringBuffer 是因为StringBuffer是线程安全的,在新增数据时会进行加锁操作,所以速度比起 StringBuilder会慢一些。
线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的。因为StringBuffer中方法都被Synchronized修饰
使用总结
1.如果要操作少量的数据,用String ;单线程操作大量数据,用StringBuilder ;多线程操作大量数据,用StringBuffer。
2.不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。
3.相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用 StringBuilder;否则还是用 StringBuffer。
4.为了获得更好的性能,在构造 StringBuffer 或 StringBuilder 时应尽可能指定它们的容量。当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。不指定容量会显著降低性能。