美文网首页
String和StringBuilder的区别详解(源码)

String和StringBuilder的区别详解(源码)

作者: 是一动不动的friend | 来源:发表于2017-10-08 20:33 被阅读13次

    String是Object类的子类。
    StringBuilder和StringBuffer同为AbstractStringBuilder的子类,而
    AbstractStringBuilder这个抽象类中定义了该参数

    char[] value;
    

    回忆一下在String类的源码中是这样定义的;

    private final char value[];
    

    两者的区别就在于String中的value[]虽然是final但是该引用指向的内容是可变的,不过String中没有提供更改的接口,所以内容也是不可变的。反观AbstractStringBuilder中的value[]则可以供他人更改。
    *StringBuilder(可变字符序列),String(不可变字符序列)

    1.内存分析:
    举个例子:我们要把1到100的所有数字拼起来,组成一个字符串

    StringBuffer sbf = new StringBuffer();
    for(int i = 0;i<100;i++)
    {
          sbf.append(i);
    }
    

    上面使用StringBuffer和append()方法拼接字符串的方法要比下面使用String的方法高效很多。原因就在于,String在jvm中是不可变的下面看起来str改变了是因为创建了多个字符串,且让str指向改变。
    这样一来,用String来实现的方法会创建101个对象。远多于StringBuffer。

    String str= new String();
    for(int i = 0;i<100;i++)
    {
          str = str+i;
    }
    

    2.动态数组扩容:数组一旦创建它的大小就不可变了。(注:在数组中length是属性,而在String中length()是方法,而在StringBuffer的父类AbstractStringBuilder中也有length方法)那么StringBuffer是如何实现数组扩容的呢?
    StringBuffer在扩容时会用super()调用父类的重载构造方法。

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

    父类AbstractStringBuilder中:

    void expandCapacity(int minimumCapacity) {
            int newCapacity = value.length * 2 + 2;
            if (newCapacity - minimumCapacity < 0)
                newCapacity = minimumCapacity;
            if (newCapacity < 0) {
                if (minimumCapacity < 0) // overflow
                    throw new OutOfMemoryError();
                newCapacity = Integer.MAX_VALUE;
            }
            value = Arrays.copyOf(value, newCapacity);
        }
    

    先判断是否需要扩容再讲述组扩容成原来的2倍加2。并把原来的数组复制到新数组中去。

    3.equals方法的实现重写:
    String中重写了equals()方法和hashCode()方法,而StringBuffer并没有重写,所以将StringBuffer类储存进集合类中时会出现问题。

    相关文章

      网友评论

          本文标题:String和StringBuilder的区别详解(源码)

          本文链接:https://www.haomeiwen.com/subject/cvidyxtx.html