文档章节

【Java部分源码分析之lang篇】4.StringBuilder与StringBuffer(二)

gongwilliam
 gongwilliam
发布于 2017/07/11 17:05
字数 703
阅读 7
收藏 0

好的,上一篇主要看了StringBuilder与StringBuffer两者共同的抽象父类AbstractStringBuilder,其实StringBuilder与StringBuffer很多功能都是在这个AbstractStringBuilder类里面已经实现了,极少部分是继承时实现。别BB,show you the code。

StringBuilder

package java.lang;

public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    static final long serialVersionUID = 4383685877147921099L;

    public StringBuilder() {
        super(16);
    }


    public StringBuilder(int capacity) {
        super(capacity);
    }

    public StringBuilder(String str) {
        super(str.length() + 16);
        append(str);
    }

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

    @Override
    public StringBuilder delete(int start, int end) {
        super.delete(start, end);
        return this;
    }

    @Override
    public StringBuilder replace(int start, int end, String str) {
        super.replace(start, end, str);
        return this;
    }

    @Override
    public StringBuilder insert(int offset, Object obj) {
            super.insert(offset, obj);
            return this;
    }
	
    @Override
    public StringBuilder reverse() {
        super.reverse();
        return this;
    }

    @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException {
        s.defaultWriteObject();
        s.writeInt(count);
        s.writeObject(value);
    }

    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
        count = s.readInt();
        value = (char[]) s.readObject();
    }

}

StringBuffer

package java.lang;

import java.util.Arrays;

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

    private transient char[] toStringCache;

    static final long serialVersionUID = 3388685877147921107L;

    public StringBuffer() {
        super(16);
    }

    public StringBuffer(int capacity) {
        super(capacity);
    }

    public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

    public StringBuffer(CharSequence seq) {
        this(seq.length() + 16);
        append(seq);
    }

    @Override
    public synchronized int length() {
        return count;
    }

    @Override
    public synchronized int capacity() {
        return value.length;
    }


    @Override
    public synchronized void ensureCapacity(int minimumCapacity) {
        super.ensureCapacity(minimumCapacity);
    }

    @Override
    public synchronized void trimToSize() {
        super.trimToSize();
    }

    @Override
    public synchronized void setLength(int newLength) {
        toStringCache = null;
        super.setLength(newLength);
    }

    @Override
    public synchronized char charAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        return value[index];
    }

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

    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }

    @Override
    synchronized StringBuffer append(AbstractStringBuilder asb) {
        toStringCache = null;
        super.append(asb);
        return this;
    }


    @Override
    public synchronized StringBuffer delete(int start, int end) {
        toStringCache = null;
        super.delete(start, end);
        return this;
    }


    @Override
    public synchronized StringBuffer replace(int start, int end, String str) {
        toStringCache = null;
        super.replace(start, end, str);
        return this;
    }

    @Override
    public synchronized String substring(int start) {
        return substring(start, count);
    }


    @Override
    public synchronized StringBuffer insert(int offset, Object obj) {
        toStringCache = null;
        super.insert(offset, String.valueOf(obj));
        return this;
    }

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

    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }
}

通过两个类的对比发现,两者的区别主要是一个关键字synchronized。我们知道synchronized是JVM级别的锁实现,所以JVM会对这个锁进行优化,但是这只是在并发量不高的情况下很好用,如果并发量很高的话,我建议是lock+StringBuilder。

StringBuilder和StringBuffer的初始化大小都是16,扩容是原来的2倍加2。

我们还注意到一个细节:

    private transient char[] toStringCache;

这个变量是用于最近一次toString()方法的缓存,任何时候只要StringBuffer被修改了这个变量会被赋值为null。这样做的作用只要是节省空间以及创建String的开销。

总结一下:

  • 性能:StringBuilder > StringBuffer > String
  • StringBuffer线程安全的机制是用了synchronized修饰符。
  • 如果要操作少量的数据用String,单线程操作字符串缓冲区 下操作大量数据StringBuilder,多线程操作字符串缓冲区 下操作大量数据StringBuffer。

© 著作权归作者所有

gongwilliam
粉丝 2
博文 14
码字总数 12127
作品 0
深圳
私信 提问
String ,  StringBuffer ,  StringBuilder的区别

String , StringBuffer , StringBuilder的区别 String 首先,String 是用来表示一个字符串常量的,它是一个不可变对象,意味着,一旦我们创建了某个字符串之后,就不能再改变它的值了,我们可...

tsmyk0715
2018/10/17
183
0
JVM第三天 Java Class File structure

Reference: http://viralpatel.net/blogs/tutorial-java-class-file-format-revealed/ A Java class file is consist of 10 basic sections: 1.Magic Number: 0xCAFEBABE 2.Version of Class......

Kerry_Han
2014/03/26
186
0
Java 208 道面试题:Java 基础模块答案

目前市面上的面试题存在两大问题:第一,题目太旧好久没有更新了,还都停留在 2010 年之前的状态;第二,近几年 JDK 更新和发布都很快,Java 的用法也变了不少,加上 Java 技术栈也加入了很多...

王磊的博客
03/05
561
0
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
2018/06/21
0
0
Groovy核心类源码讲解(终)

前两篇groovy我们从源码的角度分析了,groovy对java做了那些扩展和这些扩展的实现的原理,今天这篇文章,我们来讲解groovy源码分析中的最后一部分,来分析一下groovy中最后一部分对java做了那...

qndroid
2018/07/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

领域驱动中的“贫血症和失忆症” --实践领域驱动--原文

贫血症严重危害着人类健康,并且伴随有危险的副作用。当贫血领域对象被首次提出来时,它并不是一个博得赞美的词汇,它描述的是一个缺少内在行为领域对象。奇怪的是,人们对于贫血领域对象的态...

还仙
18分钟前
4
0
条码打印软件中标签预览正常打印无反应怎么解决

在使用条码打印软件制作标签时,有客户反馈,标签打印预览正常的,但是打印无反应,咨询是怎么回事?今天针对这个情况,可以参考以下方法进行解决。 一、预览正常情况下,打印没反应 (1)在条码...

中琅软件
28分钟前
4
0
判断字符串的时候

判断字符串的时候一定把常量房前边, //报警程度 String leve = vo.getDeviceAlertDeal().getWarnLevel(); if(("0").equals(leve)) { row.add("无报警"); }else if(("1").equals(leve)) { ro......

简小姐
28分钟前
5
0
Linux maven3.6.2 install

PS:安装 maven 之前请先安装 jdk 1.安装 wget 命令(安装过就不用了) yum -y install wget 2.寻找需要的 maven 版本 https://maven.apache.org/download.cgi 3.进入 /var/local 文件夹 cd...

东方神祇
30分钟前
4
0
Tomcat源码分析二:先看看Tomcat的整体架构

Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server、Service、Connector、Container等组件,接下...

flygrk
33分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部