开课吧Java课堂:StringBuffer全解,非常详细

110 阅读8分钟

StringBuffer是提供了大量的字符串功能的字符串(String)类的对等类。正如你所知,字符串(String)表示了定长,不可变的字符序列。相反,StringBuffer表示了可变长的和可写的字符序列。

StringBuffer可有插入其中或追加其后的字符或子字符串。

StringBuffer可以针对这些添加自动地增加空间,同时它通常还有比实际需要更多的预留字符,从而允许增加空间。Java大量使用这两种类,但是多数程序员仅仅处理字符串(String)而通过重载+运算符让Java在后台处理StringBuffer。

StringBuffer构造函数

StringBuffer定义了下面三个构造函数: StringBuffer( ) StringBuffer(int size) StringBuffer(String str)

默认构造函数(无参数)预留了16个字符的空间。该空间不需再分配。第二种形式接收一个整数参数,清楚地设置缓冲区的大小。第三种形式接收一个字符串(String)参数,设置StringBuffer对象的初始内容,同时不进行再分配地多预留了16个字符的空间。

当没有指定缓冲区的大小时,StringBuffer分配了16个附加字符的空间,这是因为再分配在时间上代价很大。而且频繁地再分配可以产生内存碎片。StringBuffer通过给一些额外的字符分配空间,减少了再分配操作发生的次数。

length( )和capacity( ) 通过调用length( )方法可以得到当前StringBuffer的长度。而通过调用capacity( )方法可以得到总的分配容量。它们的一般形式如下:

int length( ) 
int capacity( ) 

这里是一个例子:

// StringBuffer length vs. capacity. 
class StringBufferDemo { 
 public static void main(String args[]) { 
 StringBuffer sb = new StringBuffer("Hello"); 
 System.out.println("buffer = " + sb); 
 System.out.println("length = " + sb.length()); 
 System.out.println("capacity = " + sb.capacity()); 
 } 
} 

下面是这个程序的输出,它说明了StringBuffer如何为另外的处理预留额外的空间:

buffer = Hello 
length = 5 
capacity = 21 

由于sb在创建时由字符串“Hello”初始化,因此它的长度为5。因为给16个附加的字符自动增加了存储空间,因此它的存储容量为21。

ensureCapacity( ) 如果想在构造StringBuffer之后为某些字符预分配空间,可以使用ensureCapacity( )方法设置缓冲区的大小。这在事先已知要在StringBuffer上追加大量小字符串的情况下是有用的。

ensureCapacity( )方法具有如下的一般形式:

void ensureCapacity(int capacity) 

这里capacity指定了缓冲区的大小。

setLength( ) 使用setLength( )方法在StringBuffer对象内设置缓冲区的大小。其一般形式如下:

void setLength(int len) 

这里len指定了缓冲区的长度。这个值必须是非负的。

当增加缓冲区的大小时,空字符将被加在现存缓冲区的后面。如果用一个小于length( )方法返回的当前值的值调用setLength( )方法,那么在新长度之后存储的字符将被丢失。后面的setCharAtDemo例子程序使用setLength( )方法缩短StringBuffer。

charAt( )和setCharAt( ) 使用charAt( )方法可以从StringBuffer中得到单个字符的值。可以通过setCharAt( )方法给StringBuffer中的字符置值。它们的一般形式如下:

char charAt(int where) 
void setCharAt(int where, char ch) 

对于charAt( )方法,where指定获得的字符的下标。对于setCharAt( )方法,where指定被置值的字符的下标,而ch指定了该字符的新值。对于这两种方法,where必须是非负的,同时不能指定在缓冲区之外的位置。

下面的例子说明了charAt( )和setCharAt( )方法:

// Demonstrate charAt() and setCharAt(). 
class setCharAtDemo { 
 public static void main(String args[]) { 
 StringBuffer sb = new StringBuffer("Hello"); 
 System.out.println("buffer before = " + sb); 
 System.out.println("charAt(1) before = " + sb.charAt(1)); 
 sb.setCharAt(1, 'i'); 
 sb.setLength(2); 
 System.out.println("buffer after = " + sb); 
 System.out.println("charAt(1) after = " + sb.charAt(1)); 
 } 
} 

下面是该程序的输出结果:

buffer before = Hello 
charAt(1) before = e 
buffer after = Hi 
charAt(1) after = i 
13.10.6 getChars( ) 

使用getChars( )方法将StringBuffer的子字符串复制给数组。其一般形式如下:

void getChars(int sourceStart, int sourceEnd, char target[ ], 
 int targetStart) 

这里,sourceStart指定子字符串开始时的下标,而sourceEnd指定了该子字符串结束时下一个字符的下标。这意味着子字符串包含了从sourceStart到sourceEnd–1位置上的字符。

接收字符的数组由target指定。在target内将被复制子字符串的位置下标由targetStart传递。

应注意确保target数组足够大以便能够保存指定的子字符串所包含的字符。

append( ) append( )方法将任一其他类型数据的字符串形式连接到调用StringBuffer对象的后面。

对所有内置的类型和Object,它都有重载形式。下面是其几种形式:

StringBuffer append(String str) 
StringBuffer append(int num) 
StringBuffer append(Object obj) 

每个参数调用String.valueOf( )方法获得其字符串表达式。结果追加在当前StringBuffer对象后面。对每一种append( )形式,返回缓冲区本身。它允许后续的调用被连成一串,下面的例子说明了这一点:

// Demonstrate append(). 
class appendDemo { 
 public static void main(String args[]) { 
 String s; 
 int a = 42; 
 StringBuffer sb = new StringBuffer(40); 
 s = sb.append("a = ").append(a).append("!").toString(); 
 System.out.println(s); 
 } 
} 

程序的输出如下所示:

a = 42! 

当对字符串(String)对象使用+运算符时,append( )方法是最常被调用的。Java自动地改变对字符串(String)实例的修改,就像对StringBuffer实例的操作一样。

因此,连接调用StringBuffer对象的append( )方法。在执行连接之后,编译器插入对toString( )方法的调用,将修改的StringBuffer返回到一个不变的字符串(String)中。所有这一切看起来是很复杂的。

为什么不是仅只有一个其操作或多或少地像StringBuffer的字符串类呢?答案是性能。

Java运行时执行的许多优化是知道字符串(String)对象是不可改变的。值得欣慰的是Java隐藏了大多数复杂的String与StringBuffer之间的转换。

实际上,大多数的程序员从没有直接感觉到需要使用StringBuffer,而可以根据应用于字符串(String)变量上的+运算符表示大多数的操作。

insert( )

insert( )方法将一个字符串插入另一个字符串中。它被重载而接收所有简单类型的值,包括String和Object。和append( )方法一样,它调用String.valueOf( )方法得到调用它的值的字符串表达式。随后这个字符串被插入所调用的StringBuffer对象中。下面是它们的几种形式:

StringBuffer insert(int index, String str) 
StringBuffer insert(int index, char ch) 
StringBuffer insert(int index, Object obj) 

这里index指定将字符串插入所调用的StringBuffer对象中的插入点的下标。

下面的例子程序完成在“I”和“Java”之间插入“like”的功能。

// Demonstrate insert(). 
class insertDemo { 
 public static void main(String args[]) { 
 StringBuffer sb = new StringBuffer("I Java!"); 
 sb.insert(2, "like "); 
 System.out.println(sb); 
 } 
} 

程序的输出结果如下所示:

I like Java! 

reverse( ) 可以使用reverse( )方法将StringBuffer对象内的字符串翻转,其一般形式如下:

StringBuffer reverse( ) 

这种方法返回被调用对象的翻转对象。下面的程序说明了reverse( )方法:

// Using reverse() to reverse a StringBuffer. 
class ReverseDemo { 
 public static void main(String args[]) { 
 StringBuffer s = new StringBuffer("abcdef"); 
 System.out.println(s); 
 s.reverse(); 
 System.out.println(s); 
 } 
} 

程序的输出结果如下所示:

abcdef 
fedcba 

delete( )和deleteCharAt( ) Java 2在StringBuffer中增加了用于删除字符串的方法delete( )和deleteCharAt( )。这些方法的一般形式如下:

StringBuffer delete(int startIndex, int endIndex) 
StringBuffer deleteCharAt(int loc) 

delete( )方法从调用对象中删除一串字符。这里startIndex指定了需删除的第一个字符的下标,而endIndex指定了需删除的最后一个字符的下一个字符的下标。

因此要删除的子字符串从startIndex到endIndex–1,返回结果的StringBuffer对象。deleteCharAt( )方法删除由loc指定下标处的字符,返回结果的StringBuffer对象。

这里是一个说明delete( )和deleteCharAt( )方法的程序。

// Demonstrate delete() and deleteCharAt() 
class deleteDemo { 
 public static void main(String args[]) { 
 StringBuffer sb = new StringBuffer("This is a test."); 
 sb.delete(4, 7); 
 System.out.println("After delete: " + sb); 
 sb.deleteCharAt(0); 
 System.out.println("After deleteCharAt: " + sb); 
 } 
} 

程序输出如下所示:

After delete: This a test. 
After deleteCharAt: his a test. 

replace( ) Java 2在StringBuffer中增加的另一个方法是replace( )。它完成在StringBuffer内部用一组字符代替另一组字符的功能。它的形式如下:

StringBuffer replace(int startIndex, int endIndex, String str) 

被替换的子字符串由下标startIndex和endIndex指定。从startIndex到endIndex-1的子字符串被替换。替代字符串在str中传递。返回结果的StringBuffer对象。

下面的程序说明了replace( )方法:

// Demonstrate replace() 
class replaceDemo { 
 public static void main(String args[]) { 
 StringBuffer sb = new StringBuffer("This is a test."); 
 sb.replace(5, 7, "was"); 
 System.out.println("After replace: " + sb); 
 } 
} 

输出如下所示:

After replace: This was a test. 

substring( ) Java 2也增加了substring( )方法,它返回StringBuffer的一部分值。它具有如下的两种形式:

String substring(int startIndex) 
String substring(int startIndex, int endIndex) 

第一种形式返回调用StringBuffer对象中从startIndex下标开始直至结束的一个子字符串。第二种形式返回从startIndex开始到endIndex–1结束的子字符串。这些方法与前面在String中定义的那些方法具有相同的功能。