String与StringBuffer的区别

来源:互联网 发布:英国人用淘宝 编辑:程序博客网 时间:2024/05/21 11:02

String表示的是字符串,在String的源码中存在如下:

1 public final class String2     implements java.io.Serializable, Comparable<String>, CharSequence {3     /** The value is used for character storage. */4     private final char value[];

  由于字符串是由若干个字符线性组成,在java中所有的字符串都可以用数组的形式来存储,由于所声明的数组类型加了final,以至于String成为了一个不可变的字符序列,而在实际的问题中都存在需要字符串变动的情况,针对这一情况,引入了StringBuilder,和StringBuffer,其中StringBuilder是在jdk1.5之后增加的.

既然String是封装不可变数组,那么也得有封装可变数组,就这样StringBuffer诞生了,而且还是线程安全的,由于这种线程安全的StringBuffer在非线程下效率很低,所有jdk1.5之后StringBuilder诞生了,StringBuilder是非线程安全可变字符串类,相比StringBuffer效率很高!

StringBuilder和StringBuffer类的关键源码分析:

1 public final class StringBuilder2     extends AbstractStringBuilder3     implements java.io.Serializable, CharSequence4 {
1 abstract class AbstractStringBuilder implements Appendable, CharSequence {
/**
* The value is used for character storage.
*/
2 char[] value;

 从中可以看出StringBuilder和StringBuffer都继承抽象类AbstractStringBuilder ,所以AbstractStringBuilder 也是它俩共同的父类,并且在父类中声明的数组也是可变的。

2.StringBuilder和StringBuffer默认值问题

 public final class StringBuilder 2     extends AbstractStringBuilder 3     implements java.io.Serializable, CharSequence 4 { 5  6     /** use serialVersionUID for interoperability */ 7     static final long serialVersionUID = 4383685877147921099L; 8  9     /**10      * Constructs a string builder with no characters in it and an11      * initial capacity of 16 characters.12      */13     public StringBuilder() {14         super(16);15     }16 17     /**18      * Constructs a string builder with no characters in it and an19      * initial capacity specified by the <code>capacity</code> argument.20      *21      * @param      capacity  the initial capacity.22      * @throws     NegativeArraySizeException  if the <code>capacity</code>23      *               argument is less than <code>0</code>.24      */25     public StringBuilder(int capacity) {26         super(capacity);27     }
复制代码

从中可以看出,可变数组的长度大小默认是16,所以如果当长度的大小超过默认值,又会发生什么呢?请看下面代码: 

复制代码
 1 private void ensureCapacityInternal(int minimumCapacity) { 2         // overflow-conscious code 3         if (minimumCapacity - value.length > 0) 4            //调用下面的expandCapacity方法实现“扩容”特性 5             expandCapacity(minimumCapacity); 6     } 7  8    /** 9      * This implements the expansion semantics of ensureCapacity with no10      * size check or synchronization.11      */12     void expandCapacity(int minimumCapacity) {13        //“扩展”的数组长度是按“扩展”前数组长度的2倍再加上2 byte的规则来扩展14         int newCapacity = value.length * 2 + 2;15         if (newCapacity - minimumCapacity < 0)16             newCapacity = minimumCapacity;17         if (newCapacity < 0) {18             if (minimumCapacity < 0) // overflow19                 throw new OutOfMemoryError();20             newCapacity = Integer.MAX_VALUE;21         }22         //将value变量指向Arrays返回的新的char[]对象,从而达到“扩容”的特性23         value = Arrays.copyOf(value, newCapacity);24     }
复制代码

从上述代码中可以看出当实际数组长度超过默认值时会自动进行扩容,具体是原有数组长度的两倍加2,再不够,再进行扩容!

1.并不是任何情况下StringBuilder都一定比String效率高,例如:

  效率:String>StringBuffer

1
2
String str="my"+"name"+"is";
StringBuffer Sb = new StringBuilder(“my”).append(“ name”).append(“ is”);

  效率:StringBuffer>String

1
2
3
4
String S2 = “my name is”;
 String S3 = “ gaoruilin”;
 String S4 = “ test”;
 String S1 = S2 +S3 + S4;



String与StringBuffer的区别
简单地说,就是一个变量和常量的关系。StringBuffer对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。
StringBuffer的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。
String:在String类中没有用来改变已有字符串中的某个字符的方法,由于不能改变一个Java字符串中的某个单独字符,所以在JDK文档中称String类的对象是不可改变的。然而,不可改变的字符串具有一个很大的优点:编译器可以把字符串设为共享的。 
StringBuffer:StringBuffer类属于一种辅助类,可预先分配指定长度的内存块建立一个字符串缓冲区。这样使用StringBuffer类的append方法追加字符 比 String使用 + 操作符添加字符 到 一个已经存在的字符串后面有效率得多。因为使用 + 操作符每一次将字符添加到一个字符串中去时,字符串对象都需要寻找一个新的内存空间来容纳更大的字符串,这无凝是一个非常消耗时间的操作。添加多个字符也就意味着要一次又一次的对字符串重新分配内存。使用StringBuffer类就避免了这个问题。
StringBuffer是线程安全的,在多线程程序中也可以很方便的进行使用,但是程序的执行效率相对来说就要稍微慢一些。
StringBuffer的常用方法
StringBuffer类中的方法要偏重于对字符串的变化例如追加、插入和删除等,这个也是StringBuffer和String类的主要区别。
1、append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接。调用该方法以后,StringBuffer对象的内容也发生改变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”。
使用该方法进行字符串的连接,将比String更加节约内容,例如应用于数据库SQL语句的连接,例如:
StringBuffer sb = new StringBuffer();
String user = “test”;
String pwd = “123”;
sb.append(“select * from userInfo where username=“)
.append(user)
.append(“ and pwd=”)
.append(pwd);
这样对象sb的值就是字符串“select * from userInfo where username=test and pwd=123”。
2、deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“Test”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变为”Tst”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。
3、insert方法
public StringBuffer insert(int offset, String s)
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,“false”);
该示例代码的作用是在对象sb的索引值4的位置插入字符串false,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。
4、reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。
5、setCharAt方法
public void setCharAt(int index, char ch)
该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。
6、trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费。
7、构造方法:
StringBuffer s0=new StringBuffer();分配了长16字节的字符缓冲区
StringBuffer s1=new StringBuffer(512);分配了512字节的字符缓冲区
8、获取字符串的长度: length()
StringBuffer s = new StringBuffer("www");
int i=s.length();
m.返回字符串的一部分值
substring(int start) //返回从start下标开始以后的字符串
substring(int start,int end) //返回从start到 end-1字符串
9.替换字符串
replace(int start,int end,String str)
s.replace(0,1,"qqq");
10.转换为不变字符串:toString()。


原创粉丝点击