美文网首页
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