StringBuffer、StringBuilder

 1、初始化

StringBuffer和StringBuilder就是所谓的可变字符串类,共四个构造方法:

StringBuffer()

public StringBuffer(int paramInt)

public StringBuffer(String paramString)

public StringBuffer(CharSequence paramCharSequence)

观察其源码发现,使用StringBuffer()时,默认开辟16个字符的长度的空间,使用public StringBuffer(int paramInt)时开辟指定大小的空间,使用public StringBuffer(String paramString)时,开辟paramString.length+16大小的空间。都是调用父类的构造器super()来开辟内存。这方面StringBuffer和StringBuilder都一样,且都实现AbstractStringBuilder类。

  2、主要方法

二者几乎没什么区别,基本都是在调用父类的各个方法,一个重要的区别就是StringBuffer是线程安全的,内部的大多数方法前面都有关键字synchronized,这样就会有一定的性能消耗,StringBuilder是非线程安全的,所以效率要高些。

  1. public static void main(String[] args) throws Exception {  
  2.         String string = "0";  
  3.         int n = 10000;  
  4.         long begin = System.currentTimeMillis();  
  5.         for (int i = 1; i < n; i++) {  
  6.             string += i;  
  7.         }  
  8.         long end = System.currentTimeMillis();  
  9.         long between = end - begin;  
  10.         System.out.println("使用String类耗时:" + between+"ms");  
  11.   
  12.         int n1 = 10000;  
  13.         StringBuffer sb = new StringBuffer("0");  
  14.         long begin1 = System.currentTimeMillis();  
  15.         for (int j = 1; j < n1; j++) {  
  16.             sb.append(j);  
  17.         }  
  18.         long end1 = System.currentTimeMillis();  
  19.         long between1 = end1 - begin1;  
  20.         System.out.println("使用StringBuffer类耗时:" + between1+"ms");  
  21.   
  22.         int n2 = 10000;  
  23.         StringBuilder sb2 = new StringBuilder("0");  
  24.         long begin2 = System.currentTimeMillis();  
  25.         for (int k = 1; k < n2; k++) {  
  26.             sb2.append(k);  
  27.         }  
  28.         long end2 = System.currentTimeMillis();  
  29.         long between2 = end2 - begin2;  
  30.         System.out.println("使用StringBuilder类耗时:" + between2+"ms");  
  31.     }  

 

 

 

 

 

 

输出:

使用String类耗时:982ms
使用StringBuffer类耗时:2ms
使用StringBuilder类耗时:1ms

虽然这个数字每次执行都不一样,而且每个机子的情况也不一样,但是有几点是确定的,String类消耗的明显比另外两个多得多。还有一点就是,StringBuffer要比StringBuilder消耗的多,尽管相差不明显。

接下来介绍一些常用的方法。

-----------------------public synchronized int length()--------------------------

-------------------------public synchronized int capacity()---------------------------

二者都是获取字符串的长度,length()获取的是当前字符串的长度,capacity()获取的是当前缓冲区的大小。举个简单的例子:

 

  1. StringBuffer sb = new StringBuffer();  
  2.         System.out.println(sb.length());;  
  3.         System.out.println(sb.capacity());  

输出:

 

 

 

 

 

 

0

16

 

  1. StringBuffer sb = new StringBuffer("hello");  
  2.         System.out.println(sb.length());;  
  3.         System.out.println(sb.capacity());  

输出:

 

 

 

 

 

 

5

21

因为默认分配16个字符大小的空间,所以不难解释上面的结果。

------------------public boolean equals(Object paramObject)---------------------

 

  1. StringBuffer sb = new StringBuffer("hello");  
  2.         StringBuffer sb2 = new StringBuffer("hello");  
  3.         System.out.println(sb.equals(sb2));  

以上程序输出false,是不是有点惊讶?记得之前我们的文章说过,equals()比较的是字符串的内容,按理说此处应该输出的是true才对。

 

 

 

 

 

 

究其原因,String类重写了Object的equals(),所以只需要看内容是否相等即可,但是StringBuffer没有重写equals(),此处的equals()仍然是调用的Object类的,所以,调用StringBuffer类的equals(),只有地址和内容都相等的字符串,结果才会返回true。

另外StringBuffer有一系列追加、插入、删除字符串的方法,首先append(),就是在原来的字符串后面直接追加一个新的串,和String类相比有明显的好处:

String类在追加的时候,源字符串不变(这就是为什么说String是不可变的字符串类型),和新串连接后,重新开辟一个内存。这样就会造成每次连接一个新串后,都会让之前的串报废,因此也造成了不可避免的内存泄露。

 

  1.              //append()  
  2. StringBuffer sb = new StringBuffer("helloworld, ");  
  3. sb.append("I'm ").append("erqing ").append("who ").append("are you ?");  
  4. System.out.println(sb);  
  5. //public synchronized StringBuffer insert(int paramInt, Object paramObject)  
  6. sb.insert(12, /*9*/"nice! ");  
  7. System.out.println(sb);  
  8. //public synchronized StringBuffer reverse()  
  9. sb.reverse();  
  10. System.out.println(sb);  
  11. sb.reverse();  
  12. System.out.println(sb);  
  13. //public synchronized StringBuffer delete(int paramInt1, int paramInt2)  
  14. //public synchronized StringBuffer deleteCharAt(int paramInt)  
  15. sb.delete(12, 18);  
  16. System.out.println(sb);  
  17. sb.deleteCharAt(5);  
  18. System.out.println(sb);  

输出:

 

 

 

 

 

 

helloworld, I'm erqing who are you ?
helloworld, nice! I'm erqing who are you ?
? uoy era ohw gniqre m'I !ecin ,dlrowolleh
helloworld, nice! I'm erqing who are you ?
helloworld, I'm erqing who are you ?
helloorld, I'm erqing who are you ?

-----------------public synchronized void trimToSize()---------------------

该方法用于将多余的缓冲区空间释放出来。

 

  1.               StringBuffer sb = new StringBuffer("hello erqing");  
  2. System.out.println("length:"+sb.length());  
  3. System.out.println("capacity:"+sb.capacity());  
  4. sb.trimToSize();  
  5. System.out.println("trimTosize:"+sb.capacity());  

输出:

 

 

 

 

 

 

length:12
capacity:28
trimTosize:12

StringBuffer类还有很多方法,关于字符查找,截取,替换方面的方法,有兴趣的童鞋可以去研究研究源码,定会学到不少知识!

三、字符串处理类StringTokenizer

StringTokenizer是java.util包下的一个类,用来对字符串做简单的处理。

举个简单的例子:

 

  1. String s = "Tonight is the answer !";  
  2.         StringTokenizer st = new StringTokenizer(s," ");  
  3.         int count = st.countTokens();  
  4.         System.out.println("个数为:"+count);  
  5.         while (st.hasMoreTokens()) {  
  6.             String token = st.nextToken();  
  7.             System.out.println(token);  
  8.         }  

输出:

 

 

 

 

 

 

个数为:5
Tonight
is
the
answer
!

转载于:https://my.oschina.net/u/3572551/blog/1153957

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值