String、StringBuffer、StringBuilder的对比

Java提供了String、StringBuffer和StringBuilder类来封装字符串,并提供了一系列操作字符串对象的方法。

三者的共同点是都用来封装字符串、都实现了CharSequence接口、底层都使用char[]存储。但是它们之间也存在不同点。

三者部分源码

String部分源码 

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence 
{
    
    private final char value[];

    private int hash; // Default to 0

    private static final long serialVersionUID = -6849794470754667710L;

    private static final ObjectStreamField[] serialPersistentFields =
     new ObjectStreamField[0];

      public String() 
      {
       this.value = "".value;
      }
      public String(String original) 
      {
         this.value = original.value;
         this.hash = original.hash;
      }
      public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
      }
      public boolean equals(Object anObject) 
      {
        if (this == anObject) {
          return true;
        }
        if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        if (n == anotherString.value.length) {
         char v1[] = value;
         char v2[] = anotherString.value;
         int i = 0;
         while (n-- != 0) {
          if (v1[i] != v2[i])
            return false;
              i++;
             }
             return true;
           }
       }
       return false;
      }
       public int hashCode() {
         int h = hash;
          if (h == 0 && value.length > 0) {
          char val[] = value;

       for (int i = 0; i < value.length; i++) {
         h = 31 * h + val[i];
        }
          hash = h;
         }
         return h;
       }
        public int indexOf(int ch) {
          return indexOf(ch, 0);
        }
    ...
}

StringBuffer部分源码

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);
    }
  ...
}

StringBuilder部分源码

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);
    }

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

1.是否可变?

String 是被 final 修饰的,是不可变的字符序列,是字符串常量,即使调用 String 的concat 方法,也只是把字符串拼接起来,把拼接后的 String 的值赋给新创建的对象。

StringBuffer 和 StringBuilder 是可变的字符序列,是字符串变量,类的对象能够被多次的修改,并且不产生新的未使用对象。

2.线程是否安全?

String中的对象是不可变的,是被final修饰的,是字符串常量,是线程安全的。

StringBuffer对象在缓冲区被多个线程使用时,它的中的方法大都使用了synchronized 关键字进行修饰,加了同步锁,所以是线程安全的。

StringBuilder是jdk5.0新增的,在使用时没有被synchronized 关键字修饰,不能保证线程安全,可能会出现一些操作错误。

AbstractStringBuilder是StringBuilder和StringBuffer的公共父类,定义了一些字符串的基本操作,它们的用法基本相同。

多线程情况下建议使用StringBuffer,单线程建议使用速度较快的StringBuilder。

3.执行效率

StringBuilder最高,StringBuffer次之,String最低。

4.初始化方式

创建String对象时,可以利用构造方法String str = new String("haha")的方式来对其进行初始化,也可以直接用赋值的方式String s = "haha"来进行初始化。而StringBuffer只能使用构造方法StringBuffer sb = new StringBuffer("hahaha")的方式来进行初始化。

5.是否实现了hashCode和equals方法

String实现了equals和hashCode方法,new String("haha").equals(new String("haha"))的结果为true;

而StringBuffer没有实现equals和hashCode方法,new StringBuffer("heihei").equals(new StringBuffer("heihei"))的结果为false。

6.使用场景

由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。

然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。 append方法与直接使用+串联相比,减少常量池的浪费。

一般而言,如果要操作少量的数据时,优先使用String类;如果是在单线程下操作大量数据,优先使用StringBuilder类;如果是在多线程下操作大量的数据,优先使用StringBuilder类。

posted @ 2019-07-16 22:05  难得糊涂1998  阅读(176)  评论(0编辑  收藏  举报