日志

浅析String、StringBuilder、StringBuffer

 来源    2020-05-23    0  

谈谈我对 String、StringBuilder、StringBuffer 的理解

StringBuilder、StringBuffer 和 String 一样,都是用于存储字符串的。

1、那既然有了 String ,为什么还需要他们两个呢?

原因是 String 是不可变的,它每次的字符串拼接,实际上都会 new 一个新的 String 进行接收。

2、谈谈StringBuilder、StringBuffer他们两个的联系:

我们可以知道 StringBuffer 在 1.0 的时候就发布了,那为什么还需要 StringBuilder 呢?原因是它的大部分方法都上了锁,是线程安全的,导致了效率较低!而我们有时候不需要考虑线程安全问题,追求效率!所以 StringBuilder 在 1.5 的时候就出来了!

3、StringBuilder、StringBuffer 的异同:*

不同:

  • StringBuffer 它因为追求安全,给大量方法上锁,线程安全!
  • StringBuilder 它因为追求效率,没有给方法上锁,线程不安全!

相同:内部方法和 StringBuffer 完全一致,因为都继承了 AbstractStringBuilder,底层数组都是用父类的。

4、源码浅析 String:

结论:final 修饰了底层的字符数组,故内容不可变。

5、源码浅析 StringBuilder:构造方法

观察构造方法:

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

结论:可以看出,它有一个默认的长度 16!而当传入参数是一个字符或者字符串时,它也会自动的传入参数的长度上加上 16!

6、源码浅析 StringBuilder:append 方法

@Override
    public StringBuilder append(Object obj) {
        return append(String.valueOf(obj));
    }

    @Override
    public StringBuilder append(String str) {
        super.append(str);
        return this;
    }

我们发现,它还是调用的父类的 append 方法,说明这个方法他并没有重写,那么 StringBuffer 也一样!

public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }

结论:我们可以看出,他也是可以拼接 null 的!

private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }

然后观察,它接着进行了一个数组容量的判断,而数组的扩容,其实就是在里面实现的,我们点进去看一下!

private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }

结论:它先是判断,当前数组容量+拼接字符 是否大于 数组长度,如果大于,则进行数组拷贝,并将底层数组的引用指向新数组!

private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }

结论:由此可见,新数组长度扩容为原数组的 2倍+2

问题:那它究竟是怎么拼接字符串的呢?

sb.getChars(0, len, value, count);

进去看一下:String 的 getChars 方法

public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
    {
        if (srcBegin < 0)
            throw new StringIndexOutOfBoundsException(srcBegin);
        if ((srcEnd < 0) || (srcEnd > count))
            throw new StringIndexOutOfBoundsException(srcEnd);
        if (srcBegin > srcEnd)
            throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

实际调用了一个系统类方法:arraycopy,再点进去看一下!

public static native void arraycopy(Object src,  int  srcPos,
                                        Object dest, int destPos,
                                        int length);

结论:底层最终是调用的本地方法,实现了的字符数组拷贝,但由于本地方法是可以和操作系统直接打交道的,所以它的 append 字符串拼接效率会高于 String!

相关文章
浅析String、StringBuffer、StringBuilder的区别以及性能区别
日志前奏: 比较三者之间的区别在与区别他们做相同的事情的时候的区别,那就是在我们常见的拼接字符串的时候,StringBuffer.StringBuilder调用的是appende()方法,而String很 ...
1
JDK源码分析系列---String,StringBuilder,StringBuffer
日志1.String public final class String implements java.io.Serializable, Comparable<String>, CharSe ...
阿里面试实战题3----String,StringBuilder,StringBuffer区别
日志String public final class String implements java.io.Serializable, Comparable<String>, CharSequ ...
基础笔记3(一)(String StringBuilder StringBuffer 数组)
日志---恢复内容开始--- 1数组.有序的同类型的集合. 2.string :字符串类型:其实就是一个字符数组.添加了private final,所以string是一个不可以变的字符串. String. ...
1
String,StringBuilder,StringBuffer的对比测试
日志public class TestString { private static final int COUNT = 10000000; public static void main(String ...
1
difference among String,StringBuilder,StringBuffer
日志difference among String,StringBuilder,StringBuffer String常用构造函数 String(byte[] bytes) String(byte[] b ...
String,StringBuilder,StringBuffer
日志转自:http://www.cnblogs.com/fancydeepin/archive/2013/04/23/min-snail-speak_String-StringBuffer-StringB ...
1
String,StringBuilder,StringBuffer区别
日志String类是final类,也即意味着String类不能被继承,并且它的成员方法都默认为final方法 只有在确定不想让该方法被覆盖时,才将方法设置为final 无论是sub操.concat还是re ...
1
C#中String StringBuilder StringBuffer
日志     String和StringBuilder和StringBuffer,这三个都是值得深究一翻的,可能很多人会说,实在不行的话,都全部用StringBuilder,啥事没有,我不能说你的想法事不 ...
String、Stringbuffer和Stringbuilder之间的区别
日志关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下 1.在执行速度方面:Stringbuilder>Stringbuffer&g ...
1
Java——String,StringBuffer和StringBuilder
日志Java——String,StringBuffer和StringBuilder 摘要:本文主要介绍了String字符串在内存中的存储情况,以及StringBuffer和StringBuilder的区别 ...
1
浅谈String、StringBuffer与StringBuilder
日志浅谈String.StringBuffer与StringBuilder 先详细介绍一下String.StringBuffer与StringBuilder String: 官方对String的说明:St ...
1
第二十节:详细讲解String和StringBuffer和StringBuilder的使用
日志前言 在 Java中的字符串属于对象,那么Java 中提供了 String 类来创建和操作字符串,即是使用对象:因为String类修饰的字符一旦被创建就不可改变,所以当对字符串进行修改的时候,需要使用 ...
java String、StringBuffer、StringBuilder
日志 1. 简介 String是不可变类,且是线程安全的: StringBuffer是可变类,且是线程安全的: StringBuilder是可变类,且不是线程安全的. 注:“可变/不可变”指对该类对象进行 ...
1
String、StringBuffer与StringBuilder之间区别 (转载)
日志最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,StringBuilder的东西,现在整理一下. 关于这三个类在字符串处理中的位置不言而喻,那 ...
1
String、StringBuffer与StringBuilder之间区别
日志关于这三个类在字符串处理中的位置不言而喻,那么他们到底有什么优缺点,到底什么时候该用谁呢?下面我们从以下几点说明一下. 1.三者在执行速度方面的比较:StringBuilder >  Strin ...
1
java中String、StringBuffer、StringBuilder的区别
日志Java里面提供了String,StringBuffer和StringBuilder三个类来封装字符串 0. 不当用法 String result = ""; for (Strin ...
Java ——String 类 StringBuffer 和 StringBuilder类 随机字符
日志本节重点思维导图 String 类 创建字符串 String str = "I love ai"; 在代码中遇到字符串常量时,"I love ai",编译器会使 ...
1
Java的String、StringBuffer和StringBuilder的区别
日志1.String 2.Stringbuffer 3.StringBuilder 4.三者之间的区别 5.使用策略 1.String public final class String implemen ...
1
String、StringBuffer与StringBuilder之间区别(转)
日志原文链接:String.StringBuffer与StringBuilder之间区别 最近学习到StringBuffer,心中有好些疑问,搜索了一些关于String,StringBuffer,Stri ...