全面解释java中StringBuilder、StringBuffer、String类之间的关系
来源:互联网 发布:开源wiki系统 php 编辑:程序博客网 时间:2024/05/16 09:22
StringBuilder、StringBuffer、String类之间的关系
java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,在上一篇博文中我们已经熟悉String字符串的特性和使用,而StringBuffer、StringBuilder又是怎么样的字符串类呢??他们之间的区别和关系又是什么呢??这问题经常在面试中会问到,现在总结一下,看看他们的不同与相同。
1.可变与不可变
1)String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。
private final char value[];
String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,不仅效率低下,而且大量浪费有限的内存空间。
1 String a = "a"; //假设a指向地址0x00012 a = "b";//重新赋值后a指向地址0x0002,但0x0001地址中保存的"a"依旧存在,但已经不再是a所指向的,a 已经指向了其它地址。
因此String的操作都是改变赋值地址而不是改变值操作。
2)StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。
char[] value;
StringBuffer是可变类,和线程安全的字符串操作类,任何对它指向的字符串的操作都不会产生新的对象。 每个StringBuffer对象都有一定的缓冲区容量,当字符串大小没有超过容量时,不会分配新的容量,当字符串大小超过容量时,会自动增加容量。
1 StringBuffer buf=new StringBuffer(); //分配长16字节的字符缓冲区2 StringBuffer buf=new StringBuffer(512); //分配长512字节的字符缓冲区3 StringBuffer buf=new StringBuffer("this is a test")//在缓冲区中存放了字符串,并在后面预留了16字节的空缓冲区。
StringBuffer和StringBuilder类功能基本相似,主要区别在于StringBuffer类的方法是多线程、安全的,而StringBuilder不是线程安全的,相比而言,StringBuilder类会略微快一点。对于经常要改变值的字符串应该使用StringBuffer和StringBuilder类。
2.是否多线程安全
String中的对象是不可变的,也就可以理解为常量,显然线程安全。
AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。
StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是线程安全的。看如下源码:
1 public synchronized StringBuffer reverse() {2 super.reverse();3 return this;4 }5 6 public int indexOf(String str) {7 return indexOf(str, 0); //存在 public synchronized int indexOf(String str, int fromIndex) 方法8 }
StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
StringBuffer是线程安全的,这意味着它们已经同步方法来控制访问,以便只有一个线程可以在同一时间访问一个StringBuffer对象同步代码。因此,StringBuffer的对象通常在多线程环境中是安全的,使用多个线程可以试图同时访问相同StringBuffer对象。
StringBuilder类非常相似的StringBuffer,不同之处在于它的访问不同步的,因此,它不是线程安全的。由于不同步,StringBuilder的性能可以比StringBuffer更好。因此,如果在单线程环境中工作,使用StringBuilder,而不是StringBuffer可能会有更高的性能。这也类似其他情况,如StringBuilder的局部变量(即一个方法中的一个变量),其中只有一个线程会访问一个StringBuilder对象。
3.StringBuffer和StringBuilder类的速度比较
一般情况下,速度从快到慢:StringBuilder>StringBuffer>String,这种比较是相对的,不是绝对的。(要考虑程序是单线程还是多线程)
接下来,我直接贴上测试过程和结果的代码,一目了然:
1 package com.hysum.test; 2 3 public class StringTest { 4 final static int time = 50000; //循环次数 5 /* 6 * String类测试方法 7 */ 8 public void test(String s){ 9 long begin = System.currentTimeMillis();//获取当前系统时间(毫秒数),开始10 for(int i=0; i<time; i++){11 s += "add";12 }13 long over = System.currentTimeMillis();//获取当前系统时间(毫秒数),结束14 System.out.println("操作"+s.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒");15 }16 /*17 * StringBuffer类测试方法18 */19 public void test(StringBuffer s){20 long begin = System.currentTimeMillis();21 for(int i=0; i<time; i++){22 s.append("add");23 }24 long over = System.currentTimeMillis();25 System.out.println("操作"+s.getClass().getCanonicalName()+"类型使用的时间为:"+(over-begin)+"毫秒");26 }27 /*28 * StringBuilder类测试方法29 */30 public void test(StringBuilder s){31 long begin = System.currentTimeMillis();32 for(int i=0; i<time; i++){33 s.append("add");34 }35 long over = System.currentTimeMillis();36 System.out.println("操作"+s.getClass().getName()+"类型使用的时间为:"+(over-begin)+"毫秒");37 }38 39 /*对 String 直接进行字符串拼接的测试*/40 public void test2(){//操作字符串对象引用相加类型使用的时间41 String s2 = "abcd";42 long begin = System.currentTimeMillis();43 for(int i=0; i<time; i++){44 String s = s2 + s2 +s2;45 }46 long over = System.currentTimeMillis();47 System.out.println("操作字符串对象引用相加类型使用的时间为:"+(over-begin)+"毫秒");48 }49 public void test3(){//操作字符串相加使用的时间50 long begin = System.currentTimeMillis();51 for(int i=0; i<time; i++){52 String s = "abcd" + "abcd" + "abcd";53 }54 long over = System.currentTimeMillis();55 System.out.println("操作字符串相加使用的时间为:"+(over-begin)+"毫秒");56 } 57 public static void main(String[] args) {58 // TODO Auto-generated method stub59 String s1 = "abcd";60 StringBuffer st1 = new StringBuffer( "abcd");61 StringBuilder st2 = new StringBuilder( "abcd");62 StringTest tc = new StringTest();63 tc.test(s1);64 tc.test(st1);65 tc.test(st2);66 tc.test2();67 tc.test3(); 68 }69 70 }
运行结果:
结果分析:
从上面的结果可以看出,不考虑多线程,采用String对象时,执行时间比其他两个都要高得多,而采用StringBuffer对象和采用StringBuilder对象的差别也比较明显;而以String类为例,操作字符串对象引用相加类型使用的时间比直接/操作字符串相加使用的时间也多得多。由此可见,如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是StringBuffer;能直接操作字符串不用字符串引用就直接操作字符串。
4、StringBuilder与StringBuffer共同点
StringBuilder与StringBuffer有公共父类AbstractStringBuilder(抽象类)。
StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(...)。只是StringBuffer会在方法上加synchronized关键字,进行同步。
那么我们接来下看一下它们的主要方法吧~
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- 解释java中StringBuilder、StringBuffer、String类之间的关系
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系 详细出处参考:http://www.jb51.net/article/33398.htm
- java中StringBuilder、StringBuffer、String类之间的关系
- java中StringBuilder、StringBuffer、String类之间的关系
- java中StringBuilder、StringBuffer、String类之间的关系
- java中StringBuilder、StringBuffer、String类之间的关系
- java中StringBuilder、StringBuffer、String类之间的关系
- java中的域是什么?
- /bin/sh^M: bad interpreter: No such file or directory 解决办法
- 推荐两份学习 Kotlin 和机器学习的资料
- sql中关于时间的函数用法整理
- 有故障的打字机 题解
- 全面解释java中StringBuilder、StringBuffer、String类之间的关系
- java反射在单元测试中的应用
- 华为机试题 计算字符个数
- 哈工大锐捷网络处理问题
- Linux上搭建shadowsocks服务
- java 在线编辑模版 代码编辑器 兼容手机平板PC freemaker 静态引擎 网站源码
- 下载和安装python
- #python练习#leetcode392. Is Subsequence【贪心】
- 欢迎使用CSDN-markdown编辑器