• 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类。


    作  者:sweetheart1998
    出  处:https://home.cnblogs.com/u/gujun1998/
    如有问题或建议,请多多赐教!
    版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
    如果您觉得文章对您有帮助,可以点击文章右下角推荐一下!

  • 相关阅读:
    如何提高软件可维护性
    UML系列 (二)四种关系
    软件工程
    软件工程需求规格说明书
    机房收费系统可行性分析报告
    ThreadStaticAttribute 的使用
    WPF:Border 控件
    几篇介绍在页面中引用脚本文件的技术文档
    收集两篇介绍 Fildder 的文章
    收集三篇关于数据库主键设计的文章
  • 原文地址:https://www.cnblogs.com/gujun1998/p/11197845.html
Copyright © 2020-2023  润新知