A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 SEPARATOR 于 2014-6-28 13:45 编辑

StringBuilder; StringBuffer,String,是经常用到的三个类。对这三个类之间的关系很迷糊,由其是StringBuilder; StringBuffer,不知道什么时候应该用哪一个?
能否简要明了地说一下区别以及什么时候应用,谢谢!

2 个回复

倒序浏览
如果要操作少量的数据用用 String
单线程操作字符串缓冲区 下操作大量数据 = StringBuilder(多线程下是不安全的,但是单线程下速度快)
多线程操作字符串缓冲区 下操作大量数据 = StringBuffer
回复 使用道具 举报
本帖最后由 贤钰 于 2014-6-28 13:11 编辑

String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间,StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象,StringBuffer和StringBuilder类功能基本相似
1. String 类

  String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。
String a = "a"; //假设a指向地址0x0001
a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。
因此String的操作都是改变赋值地址而不是改变值操作。

2. StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。

StringBuffer buf=new StringBuffer(); //分配长16字节的字符缓冲区
StringBuffer buf=new StringBuffer(512); //分配长512字节的字符缓冲区
StringBuffer buf=new StringBuffer("this is a test")//在缓冲区中存放了字符串,并在后面预留了16字节的空缓冲区。

3.
StringBuilder
  StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。

4.线程安全
StringBuffer 线程安全
StringBuilder 线程不安全

5.速度
一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。

6.总结
(1).如果要操作少量的数据用 = String
(2).单线程操作字符串缓冲区 下操作大量数据 = StringBuilder
(3).多线程操作字符串缓冲区 下操作大量数据 = StringBuffer

以下是代码与演示说明:
  1. public class TestCharacter {
  2. final static int time = 50000; //循环次数

  3. public TestCharacter(){

  4. }
  5. public void test(String s){
  6. long begin = System.currentTimeMillis();
  7. for(int i=0; i<time; i++){
  8. s += “add”;
  9. }
  10. long over = System.currentTimeMillis();
  11. System.out.println(“操作”+s.getClass().getName()+”类型使用的时间为:”+(over-begin)+”毫秒”);
  12. }
  13. public void test(StringBuffer s){
  14. long begin = System.currentTimeMillis();
  15. for(int i=0; i<time; i++){
  16. s.append(“add”);
  17. }
  18. long over = System.currentTimeMillis();
  19. System.out.println(“操作”+s.getClass().getCanonicalName()+”类型使用的时间为:”+(over-begin)+”毫秒”);
  20. }
  21. public void test(StringBuilder s){
  22. long begin = System.currentTimeMillis();
  23. for(int i=0; i<time; i++){
  24. s.append(“add”);
  25. }
  26. long over = System.currentTimeMillis();
  27. System.out.println(“操作”+s.getClass().getName()+”类型使用的时间为:”+(over-begin)+”毫秒”);
  28. }

  29. /*对 String 直接进行字符串拼接的测试*/
  30. public void test2(){
  31. String s2 = “abcd”;
  32. long begin = System.currentTimeMillis();
  33. for(int i=0; i<time; i++){
  34. String s = s2 + s2 +s2;
  35. }
  36. long over = System.currentTimeMillis();
  37. System.out.println(“操作字符串对象引用相加类型使用的时间为:”+(over-begin)+”毫秒”);
  38. }
  39. public void test3(){
  40. long begin = System.currentTimeMillis();
  41. for(int i=0; i<time; i++){
  42. String s =”abcd” + “abcd” + “abcd”;
  43. }
  44. long over = System.currentTimeMillis();
  45. System.out.println(“操作字符串相加使用的时间为:”+(over-begin)+”毫秒”);
  46. }
  47. public static void main(String[] args){
  48. String s1 = “abcd”;
  49. StringBuffer st1 = new StringBuffer(“abcd”);
  50. StringBuilder st2 = new StringBuilder(“abcd”);
  51. TestCharacter tc = new TestCharacter();
  52. tc.test(s1);
  53. tc.test(st1);
  54. tc.test(st2);
  55. tc.test2();
  56. tc.test3();
  57. }
  58. }
复制代码






评分

参与人数 1技术分 +1 收起 理由
菜小徐 + 1

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马