Concept
在字符串不经常变化的情况下,我们优先选择String。
String“+”拼接也可以用来对字符串进行修改,在String str = “I” + “am” + “String”
时候效率比较快,但是在用“+”拼接多个String对象耗费空间且执行效率低下(新建对象、回收对象花费大量时间),特别是当内存中无引用对象多了以后,JVM的GC就开始工作,对系统性能会产生影响。
StringBuffer是为了解决大量拼接字符串时产生很多中间对象问题而提供的类,他是一个线程安全的可变字符序列,类似于字符串,但是可以修改。
StringBuilder作为JDK 5 发布后对StringBuffer的补充类,与StringBuffer是等价类,只不过他是为单线程专门设计的。
StringBuffer
- 在任何时候,StringBuffer包含一些特定的字符序列,但序列的长度和内容可以通过特定的方法调用进行修改。
- StringBuffer对于使用多线程时是十分安全的,它的方法在必要时是同步的,以便对任何特定的实例的所有操作都像按照特定序列顺序发生,这与每个单线程发出的方法调用顺序一致的。
- 对于StringBuffer的主要操作是append和insert方法,这些方法都被进行了重载,以至于能接受任何形式的数据。
- 每个StringBuffer都有一个容量。只要StringBuffer内的字符串序列的长度不超过其容量,它就不会分配一个新的内部缓冲区数组空间。如果内部缓冲区溢出,它将自动扩充空间。
StringBuilder
- StringBuilder是一个可变的字符串序列。这个类提供了与StringBuffer并存的API,但是这些方法并不能保证同步。这个类被设计来作为StringBuffer的替代,在那些StringBuffer被单线程使用的时候(往往是大多数情况)。
- StringBuilder的实例在被多线程使用时并不安全。如果需要线程同步,建议使用StringBuffer。
Method
Type | Method | Significance |
---|---|---|
StringBuffer | append(int i) | 有许多重载形式,添加参数的String表示到buffer的末尾 |
StringBuffer | insert(int offset,int i) | 有许多重载形式,添加参数的String表示到指定位置 |
char | charAt(int index) | 返回序列中指定索引的char值 |
StringBuffer | delete(int start, int end) | 移除序列中子串字符 |
int | indexOf(String str) | 返回指定子串首次出现的索引 |
int | lastIndexOf(String str) | 同上,从后往前搜索 |
int | length() | 返回buffer中字符个数 |
StringBuffer | replace(int start, int end,String str) | 用参数子串字符替换指定子串字符 |
StringBuffer | reverse() | 反转序列 |
void | setCharAt(int index,char ch) | 将索引为i的字符设置为ch |
CharSequence | subSequence(int start, int end) | 返回子串的一个新的char序列 |
String | substring(int start,[int end]) | 返回子串的String形式 |
String | toString() | 返回序列中数据的String表示 |
StringBuilder与StringBuffer方法相同
Example
public class test{
public static void main(String args[]){
StringBuilder str = new StringBuilder();
str.append("BuilderBuffer");
System.out.println(str);//BuilderBuffer
//用append向StringBuilder中添加字符
str.insert(7,"and");
System.out.println(str);//BuilderandBuffer
//用append向StringBuilder中插入字符
System.out.println(str.charAt(4));//d
//返回索引4的char值
System.out.println(str.indexOf("B"));//0
System.out.println(str.lastIndexOf("B"));//10
//从前和从后搜索相同字符B 返回索引值并不一样
System.out.println(str.length());//16
//返回StringBuilder字符长度
System.out.println(str.replace(7,10,"or"));//BuilderorBuffer
//用参数替换指定位置字符串
System.out.println(str.subSequence(7,9) instanceof CharSequence);//true
//返回char序列子字符串
System.out.println(str.substring(9,15));//Buffer
//返回String类型子字符串
System.out.println(str.delete(7,9));//BuilderBuffer
//删除指定位置的字符
System.out.println(str.reverse());//reffuBredliuB
//反转序列
String str2 = str.toString();
System.out.println(str2);//reffuBredliuB
//调用toString方法 返回一个String对象
}
}
Difference
-
与String类不同的是,StringBuffer和StringBuilder类的对象能够被多次地修改,并且不产生新的未使用对象。
-
如果要操作少量数据,用String。如有大量的字符串操作情况,在单线程情况下,应该使用StringBuilder来操作字符串,多线程情况下,应该使用StringBuffer。
-
我们在总体上应该更加青睐于StringBuilder,它支持与StringBuffer相同的操作,并且比它更快,因为这些方法在执行时是非同步的。