StringBuilder和StringBuffer

  前面讲到String是不可变的,如果需要可变的字符串将如何使用和操作呢?JAVA提供了连个操作可变字符串的类,StringBuilder和StringBuffer,从源码中可以看到这两个类都是采用final修饰,并且继承抽象类AbstractStringBuilder的。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;

    /**
     * The count is the number of characters used.
     */
    int count;
}

  同String相同,都是采用字符数组来存储的,但是String中使用final修饰,是不可变的。

  StringBuffer和StringBuilder都提供了一些常用的操作字符串的方法,有什么不同之处呢?还是从源码着手分析:

StringBuffer源码解析

  /**
     * Constructs a string buffer with no characters in it and an
     * initial capacity of 16 characters.
     */
    public StringBuffer() {
        super(16);
    }

  看AbstractStringBuilder可知:

AbstractStringBuilder(int capacity) {
  value = new char[capacity];
}

  无参构造函数,构造一个初始容量为16的字符串缓冲区。同时提供多个有参的构造函数,其中:

  /**
     * Constructs a string buffer initialized to the contents of the
     * specified string. The initial capacity of the string buffer is
     * {@code 16} plus the length of the string argument.
     *
     * @param   str   the initial contents of the buffer.
     */
    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

  这个构造函数需提供一个字符串参数,构造一个字符串缓冲区,并将其内容初始化为指定的字符串内容,该字符串的初始容量为 16 加上字符串参数的长度。其中的append方法是重要部分。

    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }

    // AbstractStringBuilder
    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

  append方法前加了同步锁,保证了线程安全,StringBuffer中很多方法都采用同步锁,保证了多线程操作时的同步安全。

  其中的ensureCapacityInternal方法中对存储空间的分配:当存储空间不够用的时候,重新new char[],存储空间为:(原始大小+1)*2,最大为:Integer.MAX_VALUE ,

StringBuilder

  StringBuilder通StringBuffer操作逻辑基本一致,只是没有做同步处理。

总结

  String:字符常量

  StringBuffer:字符变量【线程安全】

  StringBuilder:字符变量【非线程安全】

  由此也可知,在大部分情况下,三者在执行速度方面的比较:StringBuilder >  StringBuffer  >  String

  用法总结:

  String:用于少量需要对字符串进行操作【因为String 每次生成对象都会对系统性能产生影响,当内存中无引用对象产生过多时,GC就会开始工作】

  StringBuilder:单线程下,多次大量操作字符串【字符串处理时不会产生新的对象,而是对象自身做改变】

  StringBuffer:多线程下,多次大量操作字符串【字符串处理时不会产生新的对象,而是对象自身做改变】

源码记:苦人所不苦,能人所不能,所谓成也
声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址,如发现错误,欢迎批评指正。  

JDK源码学习--String篇(四) 终结篇的更多相关文章

  1. JDK源码学习--String篇(二) 关于String采用final修饰的思考

    JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JD ...

  2. JDK源码学习--String篇(三) 存储篇

    在进一步解读String类时,先了解下内存分配和数据存储的. 数据存储 1.寄存器:最快的存储区,位于处理器的内部.由于寄存器的数量有限,所以寄存器是按需分配. 2.堆栈:位于RAM中,但是通过堆栈指 ...

  3. JDK源码学习--String篇(-)

    工作三年了,用了三年的JAVA,突然发现竟然没有好好的看下JDK的源码,整天用着的String,只是大概知道怎么回事,其中的实现逻辑却是一头雾水. 知耻而后勇,加油!!! java.lang.Stri ...

  4. JDK源码学习系列03----StringBuffer+StringBuilder

                         JDK源码学习系列03----StringBuffer+StringBuilder 由于前面学习了StringBuffer和StringBuilder的父类A ...

  5. JDK源码学习系列01----String

                                                     JDK源码学习系列01----String 写在最前面: 这是我JDK源码学习系列的第一篇博文,我知道 ...

  6. JDK源码学习系列02----AbstractStringBuilder

     JDK源码学习系列02----AbstractStringBuilder 因为看StringBuffer 和 StringBuilder 的源码时发现两者都继承了AbstractStringBuil ...

  7. JDK源码学习笔记——LinkedHashMap

    HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序. LinkedHashMap保证了元素迭代的顺序.该迭代顺序可以是插入顺序或者是访问顺序.通过维护一个 ...

  8. JDK1.8源码学习-String

    JDK1.8源码学习-String 目录 一.String简介 String类是Java中最常用的类之一,所有字符串的字面量都是String类的实例,字符串是常量,在定义之后不能被改变. 二.定义 p ...

  9. JDK源码学习系列05----LinkedList

                                             JDK源码学习系列05----LinkedList 1.LinkedList简介 LinkedList是基于双向链表实 ...

随机推荐

  1. 关于关注和取消关注的nodejs写法

    本例子的关注和取消关注,是通过ajax的方法实现的:nodejs后台写好api接口:响应前台的ajax 先看ajax的代码实现: // 用户关注标签 function subscribe(uid, t ...

  2. javaScript滚动新闻之上下左右平滑滚动

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  3. How to set custom JsonSerializerSettings for Json.NET in MVC 4 Web API?

    ou can customize the JsonSerializerSettings by using theFormatters.JsonFormatter.SerializerSettings  ...

  4. POJ2553-The Bottom of a Graph

    id=2553">主题链接 题意:求解Bottom(G).即集合内的点能够互相到达. 思路:有向图的强连通.缩点,找出出度为0的点,注意符合的点要按升序输出. 代码: #include ...

  5. JFreeChat

    JFreeChart教程(一) 分类: java Component2007-05-31 15:53 39849人阅读 评论(30) 收藏 举报 jfreechartimportdataset图形ap ...

  6. 新手求大神,有其他swit-case的思路写这个程序么?

    两个程序: switch-case与if-else if的区别相同点:可以实现多分支结构;不同点:switch:一般只能用于等值比较.(可以进行范围运算???---学会用switch计算范围出炉的思路 ...

  7. start.sh

    JAVA_OPTS=" -Djava.awt.headless=true -Djava.net.preferIPv4Stack=true "JAVA_MEM_OPTS=" ...

  8. hdu3516

    题目大意:这个....翻译起来还真是不好说,各位四六没过的ACMer正好去原网页看看题意,过了的好孩子还是去看看原网页看看锻炼一下吧.(当然我做这道题目的时候,教练已经摆明说要用四边形不等式,所以还是 ...

  9. 怎样在超级终端和PC之间通过串口传输文件

    Windows环境下,通过SecureCRT软件,用串口向ARM开发板发送文件: 输入命令 rz,可以看到如下图所示: 选择路径点击上传即可. 如果是想从Arm开发板中把文件Down下来,则可以按照下 ...

  10. Java学习之Java中常用对象

    java的几种对象(PO,VO,DAO,BO,POJO)解释     一.PO:persistant object 持久对象,可以看成是与数据库中的表相映射的java对象.最简单的PO就是对应数据库中 ...