java基础知识—String、StringBuffer和StringBuilder

本博文主要是介绍一下String、StringBuffer和StringBuilder之间的区别和联系。

1、从类的定义看StringBuffer、StringBuilder、String的关系

首先来看一下源码中这几个类的定义如下:

//CharSequence定义
public interface CharSequence


//StringBuffer定义
 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

//StringBuilder定义
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence

//String定义
public final class String
    implements
 java.io.Serializable, Comparable<String>, CharSequence

注意:String、StringBuffer、StringBuilder都是final类型的,这意味着它们是不能被其它类继承的(我哥们去阿里面试的时候被问过)


由以上源码定义我们可以得到三者之间的关系图如下所示:


可以发现三者都实现了CharSequence接口,CharSequence其实也就是定义了字符串操作的接口,这个接口包含length(), charAt(int index),

subSequence(int start, int end)这几个API接口。而StringBuilder和StringBuffer都继承自AbstractStringBuilder类。

2、从构造函数到具体的字符串拼接操作看看String、StringBuffer、StringBuilder的区别

2.1String的构造函数

public String() {
        this.offset = 0;
        this.count = 0;
        this.value = new char[0];
    }

    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        int size = original.count;
        char[] originalValue = original.value;
        char[] v;

        if (originalValue.length > size) {
            // The array representing the String is bigger than the new
            // String itself.  Perhaps this constructor is being called
            // in order to trim the baggage, so make a copy of the array.
            int off = original.offset;
            v = Arrays.copyOfRange(originalValue, off, off + size);
        } else {
            // The array representing the String is the same
            // size as the String, so no point in making a copy.
            v = originalValue;
        }

        this.offset = 0;
        this.count = size;
        this.value = v;
    }

    /**
     * Allocates a new {@code String} so that it represents the sequence of
     * characters currently contained in the character array argument. The
     * contents of the character array are copied; subsequent modification of
     * the character array does not affect the newly created string.
     *
     * @param  value
     *         The initial value of the string
     */
    public String(char[] value) {
        this.offset = 0;
        this.count = value.length;
        this.value = StringValue.from(value);
    }
再看看String类中的contact()函数—— 将指定字符串联到此字符串的结尾。

public String concat(String str) {
        int otherLen = str.length();

        if (otherLen == 0) {
            return this;
        }

        char[] buf = new char[count + otherLen];
        getChars(0, count, buf, 0);
        str.getChars(0, otherLen, buf, count);

        return new String(0, count + otherLen, buf);
    }
从Concat函数中,我们可以知道在对字符串使用concat操作后,具体的操作new出一个等同于两个字符串连接总长度的新的char数组,然后将两个字符串复制到新的char数组中,然后返回一个新的String对象

2.2StringBuilder常见构造函数

public StringBuffer() {
    super(16);
    }


    public StringBuffer(int capacity) {
    super(capacity);
    }
从StringBuilder的构造函数中,我们可以看见StringBuilder直接调用父类(AbstractStringBuilder)的构造函数,我们再看AbstractStringBuilder的构造函数。

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    final static int[] sizeTable = {
            9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999,
            Integer.MAX_VALUE
        };

    /**
     * The value is used for character storage.
     */
    char[] value;

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

    /**
     * This no-arg constructor is necessary for serialization of subclasses.
     */
    AbstractStringBuilder() {
    }

    /**
     * Creates an AbstractStringBuilder of the specified capacity.
     */
    AbstractStringBuilder(int capacity) {
        value = new char[capacity];
    }
//其他的一些逻辑
}
从AbstractStringBuilder的构造函数中,我们可以看出StringBuilder中存储字符串其实用的是一个char数组,capacity其实就是指定这个char数组的大小。

下面我们再从StringBuilder中的append函数看看他具体是怎么做的(以 append(String str) 为例看看)。

public StringBuilder append(String str) {
        super.append(str);
        return this;
    }
来看看AbstractStringBuilder类中的append()函数

/**
     *  value 用来存储字符串.
     */
    char value[];


    /** 
     * 有效字符串的数目.
     */
    int count;
    public AbstractStringBuilder append(String str) {
        if (str == null) {
            str = "null";
        }


        int len = str.length();
        if (len == 0) {
            return this;
        }

/**
     *  判断原来用于存储字符串的values的字符串数组有没有足够的大小来存储将要新添加入StringBuilder的字符串。如果不够用,那么就调用expandCapacity(int minimumCapacity)让容量翻两倍
     */

        int newCount = count + len;
        if (newCount > value.length) {
            expandCapacity(newCount);
        }
       //getChars将字符串复制到指定的位置
        str.getChars(0, len, value, count);
        count = newCount;
        return this;
    }

 2.3  
StringBuffer构造函数 

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

    /**
     * Constructs a string buffer with no characters in it and 
     * the specified initial capacity. 
     *
     * @param      capacity  the initial capacity.
     * @exception  NegativeArraySizeException  if the capacity
     *               argument is less than 0.
     */
    public StringBuffer(int capacity) {
    super(capacity);
    }
StringBuffer也是直接调用父类(AbstractStringBuilder)的构造函数(见上面)StringBuffer的append()函数
public synchronized StringBuffer append(String str) {
    super.append(str);
        return this;
    }
还是调用父类的append函数,但是在这里有值得注意的地方,StringBuffer的append函数有一个synchronized标识符,也就是说StringBuffer中的append函数是线程安全的,通过继续查阅其他StringBuffer中的函数,我们也可以发现他们有synchronized标识符,这就不难理解为什么StringBuffer是线程安全的但是很明显加上线程控制会拖慢程序运行的速度,所以如果不需要线程控制,那么最好就用StringBuilder。


3.比较下三者之间的区别

3.1StringBuffer和StringBuilder之间的区别和联系。

StringBuilder 和 StringBuffer都是可变的字符序列。它们都继承于AbstractStringBuilder,实现了CharSequence接口;StringBuilder是非线程安全的,而StringBuffer是线程安全的但是很明显加上线程控制会拖慢程序运行的速度,所以如果不需要线程控制,那么最好就用StringBuilder。

3.2 String和StringBuffer、StringBuilder之间的区别。

StringBuffer和StringBuilder对象的内容可以修改;而String对象一旦产生后就不可以被修改,重新赋值其实是两个对象。StringBuffer(StringBuilder)的内部实现方式和String不同,StringBuffer在进行字符串处理时,不生成新的对象,在内存使用上要优于String类。所以在实际使用时,如果经常需要对一个字符串进行修改,例如插入、删除等操作,使用StringBuffer要更加适合一些。StringBuffer对象的append效率要高于String对象的"+"连接操作。
参考:
http://www.cnblogs.com/kissazi2/p/3648671.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值