美文网首页
String、StringBuilder、StringBuffe

String、StringBuilder、StringBuffe

作者: lclandld | 来源:发表于2022-01-25 20:45 被阅读0次

    一、Java String 类——String字符串常量
    字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
    需要注意的是,String的值是不可变的,这就导致每次对String的操作都会生成新的String对象,这样不仅效率低下,而且大量浪费有限的内存空间。我们来看一下这张对String操作时内存变化的图:

    image

    我们可以看到,初始String值为“hello”,然后在这个字符串后面加上新的字符串“world”,这个过程是需要重新在栈堆内存中开辟内存空间的,最终得到了“hello world”字符串也相应的需要开辟内存空间,这样短短的两个字符串,却需要开辟三次内存空间,不得不说这是对内存空间的极大浪费。为了应对经常性的字符串相关的操作,
    引入了两个新的类——StringBuffer类和StringBuild类来对此种变化字符串进行处理。

    二、Java StringBuffer 和 StringBuilder 类——StringBuffer字符串变量、StringBuilder字符串变量

    image

    对字符串进行修改的时候,需要使用 StringBuffer 和 StringBuilder 类。

    和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象

    StringBuilder 类和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。

    由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。

    三者的继承结构

    image

    三者的区别

    image

    (1)字符修改上的区别(主要,见上面分析)

    (2)初始化上的区别,String可以空赋值,后者不行,报错

    ①String

    String s = null;

    String s = “abc”;

    ②StringBuffer

    StringBuffer s = null; //结果警告:Null pointer access: The variable result can only be null at this location

    StringBuffer s = new StringBuffer();//StringBuffer对象是一个空的对象

    StringBuffer s = new StringBuffer(“abc”);//创建带有内容的StringBuffer对象,对象的内容就是字符串”

    三、可变性上
    String字符串的本质,就是在String类内部维护了一个字符数组,并且这个数组被final修饰,因此String是不可变对象

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

    StringBuffer和StringBuilder都继承于AbstractStringBuilder,不过AbstractStringBuilder内的字符数组是没有被final修饰的,因此StringBuffer和StringBuilder对象是可变的

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

    三、线程安全上
    由于String是不可变的,很显然String类是线程安全的,而StringBuffer和StringBuilder都继承于AbstractStringBuilder的一些公共方法,不过在重写时,StringBuffer对这些方法加了同步锁:

    @Override
        public synchronized int length() {
            return count;
        }
    
        @Override
        public synchronized int capacity() {
            return value.length;
        }
    
    
        @Override
        public synchronized void ensureCapacity(int minimumCapacity) {
            super.ensureCapacity(minimumCapacity);
        }
    
        /**
         * @since      1.5
         */
        @Override
        public synchronized void trimToSize() {
            super.trimToSize();
        }
    
        /**
         * @throws IndexOutOfBoundsException {@inheritDoc}
         * @see        #length()
         */
        @Override
        public synchronized void setLength(int newLength) {
            toStringCache = null;
            super.setLength(newLength);
        }
    
    

    四、是否实现了equals和hashCode方法
    String实现了equals()方法,和hashCode()方法,可以看到equals方法是比较的值,而不是引用。
    ,new String("java").equals(new String("java"))的结果为true;

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

    而StringBuffer没有实现equals()方法和hashCode()方法,因此,new StringBuffer("java").equals(new StringBuffer("java"))的结果为false,将StringBuffer对象存储进Java集合类中会出现问题。
    五、初始化方式
    当创建String对象时,可以利用构造方法String str = new String("Java")的方式来对其进行初始化,也可以直接用赋值的方式String s = "Java"来初始化。

    而StringBuffer只能使用构造方法StringBuffer sb = new StringBuffer("hello")的方式初始化。

    小结
    综上,在执行效率方面,StringBuilder最高,StringBuffer次之,String最低,
    (1)如果要操作少量的数据用 String;

    (2)多线程操作字符串缓冲区下操作大量数据 StringBuffer;

    (3)单线程操作字符串缓冲区下操作大量数据 StringBuilder

    相关文章

      网友评论

          本文标题:String、StringBuilder、StringBuffe

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