直接看源码里对StringBuffer的解释:
StringBuffer是线程安全,可变的字符序列。 StringBuffer类似于String,但可以修改。在任何时间点它都包含一些特定的字符序列,但序列的长度和内容可以通过某些方法调用来改变。StringBuffer可供多个线程使用。这些方法在必要时进行
同步,以便任何特定实例上的所有操作都表现得好像它们以某个串行顺序出现,这与所涉及的每个单独线程所进行的方法调用的顺序一致。 StringBuffer上的主要操作是 append和 insert方法,它们被重载以接受任何类型的数据。每个都有效地将给定的数据转换为字符串,然后将该字符串的字符追加或插入StringBuffer。append方法
总是在缓冲区的末尾添加这些字符; insert方法在指定点添加字符。例如,如果 z引用当前内容为“start”的StringBuffer对象,则方法调用z.append(“le”)将导致StringBuffer包含“startle”,
而z.insert(4,“le”)}会改变StringBuffer以包含“starlet”。通常,如果sb指的是StringBuffer的实例,则 sb.append(x)与sb.insert(sb.length(),x)具有相同的效果。 每当涉及源序列的操作发生时(例如从源序列追加或插入),此类仅在执行操作的StringBuffer上同步,而不在源上同步。注意虽然StringBuffer设计为安全的从多个线程并发使用,如果是构造函数或
者append或insert操作传递一个跨线程共享的源序列,调用代码必须确保操作在操作期间具有一致且不变的源序列视图。这可以通过在操作调用期间持有锁的调用者,通过使用不可变的源序列,或者不跨线
程共享源序列来满足。 每个StringBuffer都有容量。只要StringBuffer中包含的字符序列的长度不超过容量,就不必分配新的内部缓冲区数组。如果内部缓冲区溢出,它会自动变大。 除非另有说明,否则将null参数传递给此类中的构造函数或方法将导致抛出NullPointerException。 从JDK 5发行版开始,这个类已经补充了一个设计用于单线程StringBuilder的等效类。 StringBuilder类通常应优先于此类使用,因为它支持所有相同的操作,但速度更快,因为它不执行同步。
我们可以得知String,StringBuffer,StringBuilder的区别:String不可变,StringBuffer可变,线程安全,StringBuilder可变,非线程安全。
关于StringBuffer有一点需要特别注意:length()和capacity()
先看源码:
public StringBuffer(CharSequence seq) { this(seq.length() + 16); append(seq); } @Override public synchronized int length() { return count; } @Override public synchronized int capacity() { return value.length; }
length()方法返回的是StringBuffer所包含的字符序列的长度,而capacity()方法返回的是StringBuffer的容量,StringBuffer对象初始容量为seq的长度+16.
我们编写一段代码验证一下:
import org.junit.Test; public class JavaTest { @Test public void test() { StringBuffer str = new StringBuffer(); System.out.println("length:"+str.length()); System.out.println("capacity:"+str.capacity()); str.append("Hello"); System.out.println("length:"+str.length()); System.out.println("capacity:"+str.capacity()); StringBuffer str2 = new StringBuffer("Hello"); System.out.println("length:"+str2.length()); System.out.println("capacity:"+str2.capacity()); } }
接下来看剑指offer上的一道算法题:
题目描述
请实现一个函数,将一个字符串中的每个空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
解法一:新建一个StringBuffer
public class Solution { public String replaceSpace(StringBuffer str) { String string = str.toString(); char[] chars = string.toCharArray(); StringBuffer str1 = new StringBuffer(); for (int i = 0; i < chars.length; i++) { if (chars[i] != ' ') { str1.append(chars[i]); }else { str1.append("%20"); } } return str1.toString(); } }
解法二:在原StringBuffer上修改
public class Solution { public String replaceSpace(StringBuffer str) { int length = str.length(); if(str == null || length <= 0) { return ""; } for (int i = 0; i < length; i++) { if(str.charAt(i) == ' ') { str.replace(i, i+1, "%20"); length = length + 2; } } return str.toString(); } }