现在的位置: 首页 > 综合 > 正文

String , StringBuffer, StringBuilder的区别

2018年05月16日 ⁄ 综合 ⁄ 共 4248字 ⁄ 字号 评论关闭

转载自:http://www.cnblogs.com/liuyhaiying/articles/945419.html

String是不可改变,定长;
StringBuffer, StringBuilder
是不定长,可改变.
     
注意:本来以为StringBuilderStringBufferequals方法是可以比较两个字符串的内容是否相等,今天才发现不是这么回事。这两个类都直接继承自Object,并且没有重写equals方法。

Java代码 
  1. StringBuilder sb1 = new StringBuilder("123");  
  2. StringBuilder sb2 = new StringBuilder("123"); System.out.println(sb1.equals(sb2)); 
  3. 输出结果是:false 

若要比较内容是否相同,sb1.toString().equals(sb2.toString())

简要的说, String 类型和 StringBuffer 类型的主要性能区别其实在于 String 是不可变的对象, 因此在每次对 String 类型进行改变的时候其实都等同于生成了一个新的 String 对象,然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,特别当内存中无引用对象多了以后, JVM GC 就会开始工作,那速度是一定会相当慢的。
      
而如果是使用StringBuffer 类则结果就不一样了,每次结果都会对 StringBuffer 对象本身进行操作,而不是生成新的对象,再改变对象引用。所以在一般情况下我们推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。而在某些特别情况下,String 对象的字符串拼接其实是被 JVM 解释成了StringBuffer 对象的拼接,所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,而特别是以下的字符串对象生成中, String 效率是远要比 StringBuffer 快的:

Java代码 
  1. String S1 = “This is only a” + “ simple” + “ test”;  
  2. StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);   

  你会很惊讶的发现,生成 String S1 对象的速度简直太快了,而这个时候 StringBuffer 居然速度上根本一点都不占优势。其实这是 JVM 的一个把戏,在 JVM 眼里,这个

String S1 = “This is only a” + “ simple” + “test”; 其实就是:
String S1 = “This is only a simple test”;
所以当然不需要太多的时间了。但大家这里要注意的是,如果你的字符串是来自另外的 String 对象的话,速度就没那么快了,譬如:


Java代码 
  1. String S2 = “This is only a”;  
  2. String S3 = “ simple”;  
  3. String S4 = “ test”;  
  4. String S1 = S2 +S3 + S4;   

这时候 JVM 会规规矩矩的按照原来的方式去做


在大部分情况下 StringBuffer > String

StringBuffer
Java.lang.StringBuffer 线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用 于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一 致。
StringBuffer
上的主要操作是 append insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。 append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
   
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”
在大部分情况下 StringBuilder> StringBuffer

java.lang.StringBuilde
java.lang.StringBuilder一个可变的字符序列是5.0新增的。此 类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。两者的方法基本相同。

通过非官方试验测试,StringBuilderStringBuffer的测试总结如下:

1 为了获得更好的性能,在构造 StirngBufferStirngBuilder时应尽可能指定它的容量。当然,如果你操作的字符串长度不超过16个字符就不用了。

2 相同情况下使用 StirngBuilder相比使用StringBuffer仅能获得 10%~15%左右的性能提升,但却要冒多线程不安全的风险。而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,因此:除非你能确定你的系统的瓶颈是在StringBuffer上,并且确定你的模块不会运行在多线程模式下,否则还是用StringBufferJ

3 用好现有的类比引入新的类更重要。很多程序员在使用 StringBuffer时是不指定其容量的(至少我见到的情况是这样),如果这样的习惯带入 StringBuilder的使用中,你将只能获得 10%左右的性能提升(不要忘了,你可要冒多线程的风险噢);但如果你使用指定容量的StringBuffer,你将马上获得 45%左右的性能提升,甚至比不使用指定容量的 StirngBuilder都快 30%左右。

 

StringBuffer指定容量:

 

StringBuffer类的创建和动态操作字符串的特性,可修改字符串

每个StringBuffer对象都能够存储由其容量指定的字符。如果超出了StringBuffer对象的容量,则容量就会自动地扩大,以容纳多出来的字符*/

package db;

import java.lang.StringBuffer;

public class W {

public static void main(String[] args){

  StringBuffer buffer=new StringBuffer("wish");

  System.out.println(buffer.toString());

  System.out.println("长度:"+buffer.length());

  System.out.println("容量:"+buffer.capacity());

  buffer.setCharAt(0, 'R');//以一个整数和字符为参数,将StringBuffer对象中指定位置的字符替换为参数中的字符

  buffer.append('!');//将参数转换成字符串,添加到StringBuffer对象的末尾

 

  buffer.append("Hello,welcome here!");

  buffer.insert(0, "Hello");//在StringBuffer对象的指定位置插入各种类型的值

  System.out.println(buffer.toString());

  System.out.println("长度:"+buffer.length());//返回StringBuffer对象的当前字符数目

  System.out.println("容量:"+buffer.capacity());//不需另外分配内在的情况下,返回StringBuffer对象可以存储的

//字符数目

  buffer.delete(0, 3);//从start 到 end

  System.out.println(buffer.toString());

  buffer.deleteCharAt(2);//删除第几个字符

  buffer.reverse();//颠倒StringBuffer对象中的内容

  System.out.println(buffer.toString());//打印字符串

 

}

}

/*StringBuffer类提供3个构造方法:

StringBuffer()默认构造方法,创建一个不包含字符,且容量为16个字符StringBuffer buffer=new StringBuffer();

StringBuffer(int)StringBuffer buffer=new StringBuffer(10)

StringBuffer(String)对象包含String参数中的字符,且初始容量等于String参数中的字符数再加上16

StringBuffer buffer=new StringBuffer("hello")

*/

/*wish

长度:4

容量:20

HelloRish!Hello,welcome here!

长度:29

容量:42

HelloRish!Hello,welcome here!

!ereh emoclew,olleH!hsiRoleH*/

 

抱歉!评论已关闭.