zoukankan      html  css  js  c++  java
  • Stringbuffer与Stringbuilder源码学习和对比

    Stringbuffer与Stringbuilder源码学习和对比

     

    String/StringBuffer/StringBuilder的异同

    (1)相同点
    观察源码会发现,三个类都是被final修饰的,是不可被继承的。
    (2)不同点
    String的对象是不可变的;而StringBuilder和StringBuffer是可变的
    查看源码可以发现,StringBuffer的实现都添加了Synchronized同步,因此StringBuffer是线程安全的,而StringBuilder不是线程安全的
    String中的offset,value,count都是被final修饰的不可修改的;而StringBuffer和StringBuilder中的value,count都是继承自AbstractStringBuilder类的,没有被final修饰,说明他们在运行期间是可修改的,而且没有offset变量。


    StringBuffer/StringBuilder源码学习

    String底层是一个char数组:

    1
    private final char value[];

    同样,StringBuffer/StringBuilder都继承了AbstractStringBuilder,
    底层的实现也是通过一个char型数组:

    1
    char[] value;

    它们的默认构造方法都是初始化一个长度为16的字符数组,

    1
    2
    3
    4
    5
    6
    7
    public StringBuilder() {
           super(16);
       }
        
     public StringBuilder() {
           super(16);
       }

    或者使用传入的容量进行初始化:

    1
    2
    3
    4
    5
    6
    7
    public StringBuilder(int capacity) {
            super(capacity);
        }
         
      public StringBuffer(int capacity) {
            super(capacity);
        }

    再具体的实现就不去看了,有用到再研究。

    使用举例

    贴一个以前学习Java的例子,

    String s1 = “hello”; 
    s1=“world”; 
    这个操作其实是:其实是创建了两个String对象。

    String s2 = "hello" 
    s2 += "world"; 
    这操作是:先创建一个String对象,在接下来进行字符串连接的时候,有创建了一个StringBuilder(jdk1.5前是StringBuffer),然后调用append()方法,最后调用toString()方法。 
    有此可以看出String对字符的操作比直接使用Stringbuffer(或者StringBuild)要多出附加的操作,而且String是不可变对象,使用String对字符串操作会产生大量的、多余java对象。所以结果是:影响性能,占用空间。 
    举例: 
    分别使用String和StringBuffer对字符串“0123456789”累加10000次,然后统计耗时多长:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    String str = "0123456789";
        String str2 = "";
       int count = 10000;
        long start = System.currentTimeMillis();
        for (int i = 0; i < count; i++) {
           str2 += str;
        }
        long end = System.currentTimeMillis();
        long time = (end - start);
        System.out.println(time);

      

    运行多次,在我的机器上平均时间约等于3300,即3.3秒,下面用StringBuffer来操作,查看结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    String str = "0123456789";
    StringBuffer sb = new StringBuffer();
    int count = 10000;
    long start = System.currentTimeMillis();
    for (int i = 0; i < count; i++) {
    sb.append(str);
    }
    String str2 = sb.toString();
    long end = System.currentTimeMillis();
    long time = (end - start);
    System.out.println(time);

      

    同样在我的机器上结果平均结果小于10,即0.01秒,两者相差300多倍,而且随着循环次数的增加这个差距逐渐增大 。

  • 相关阅读:
    Veritas NetBackup™ for OpenStack
    Win 810系统安装软件报错
    Netbackup驱动器常用命令vmoprcmd
    NBU服务端生成证书/客户端获取、更新证书方式/7656、7654、7640、76XX报错处理
    centos7之系统优化方案【转】
    pip的安装、以及使用方法。
    Python模块(导入,内置,自定义,开源)
    数据库的高可用 及 Mycat的引入
    LeetCode 第21题 合并有序链表
    Docker容器技术
  • 原文地址:https://www.cnblogs.com/zedosu/p/6661604.html
Copyright © 2011-2022 走看看