刷脸支付 进程 VMware 智慧树 Jetbains全家桶 validation jsf deployment cuda postman linux内存管理 网校直播系统 change事件 ajax的get请求 oracle查询数据库 tomcat调优和jvm调优 linux查看防火墙 mysql卸载工具 python函数参数 python插件 java写文件 java中class java如何使用 java生成当前时间 java中的泛型 linux系统教程 nginx安装教程 超级煎蛋卷 onenote2003 忧思华光玉攻略 英雄联盟体验服转换器 联发科mt6750 u盘系统下载 selinux关闭 脚本列表 ps高手教程 ps工具栏怎么调出来 数据库同步解决方案 易语言tv 淘宝图片下载器
当前位置: 首页 > 学习教程  > 编程语言

string和stringbuffer和stringbuilder的区别及扩容

2021/1/22 23:09:20 文章标签:

string和stringBuffer和stringbuilder的区别及扩容 1.String类 我前面写了一篇文章详细介绍了String,这里就不再赘述了。感兴趣的小伙伴可以点击此链接String详解 2.StringBuffer类 StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuf…

string和stringBuffer和stringbuilder的区别及扩容

1.String类

我前面写了一篇文章详细介绍了String,这里就不再赘述了。感兴趣的小伙伴可以点击此链接String详解

2.StringBuffer类

StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。
StringBuffer被final修饰不可被继承

 public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{

StringBuffer是线程安全的,它的绝大多数方法都做了同步处理(被synchronized修饰)

 @Override
    public synchronized StringBuffer append(double d) {
        toStringCache = null;
        super.append(d);
        return this;
    }
    @Override
    public synchronized StringBuffer replace(int start, int end, String str) {
        toStringCache = null;
        super.replace(start, end, str);
        return this;
    }

toString方法会进行对象缓存,减少元素复制开销。

    @Override
    public synchronized String toString() {
        if (toStringCache == null) {
            toStringCache = Arrays.copyOfRange(value, 0, count);
        }
        return new String(toStringCache, true);
    }

3.StringBuilder类

StringBuilder类也代表可变字符串对象。实际上,StringBuilder和StringBuffer基本相似,两个类的构造器和方法也基本相同。
不同的是:StringBuffer是线程安全的,没有同步处理(没有被synchronized修饰),所以它比StringBuffer 要快。

@Override
    public StringBuilder append(double d) {
        super.append(d);
        return this;
    }
    @Override
    public StringBuilder replace(int start, int end, String str) {
        super.replace(start, end, str);
        return this;
    }

toString方法直接返回一个Sting对象

 @Override
    public String toString() {
        // Create a copy, don't share the array
        return new String(value, 0, count);
    }

4.StringBuffer和StringBuilder的扩容

StringBuffer和StringBuilder的扩容机制是一样的。这里以StringBuilder为例
StringBuilder对象可以通过length()方法获取实体中存放的字符序列长度,通过capacity()方法来获取当前实体的实际容量。
在没有传参的情况下默认初始容量是16。

  public StringBuilder() {
        super(16);
    }

指定分配给该对象的实体的初始容量

 public StringBuilder(int capacity) {
        super(capacity);
    }

有参数的情况下,初始容量是16+字符串的长度,并且是用append()方法追加的字符

public StringBuffer(String str) {
        super(str.length() + 16);
        append(str);
    }

如果要添加的数据底层数组存不下了,那就需要扩容底层的数组。

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

通过源码我们发现它是这么扩容的 int newCapacity = (value.length << 1) + 2。<< 是位运算符,相当于乘以2,即原来的位数扩容为原来的两倍,然后再加2;这个时候如果还是放不下,那就直接扩容到它需要的长度 newCapacity = minCapacity。扩容好后将原有数组中的元素复制到新的数组中。
可能有小伙伴会有疑问,为什么扩容是2倍+2?为什么要+2?
请注意传入参数int,意味着这里传入参数可以是0,那么在参数是0的情况下,0<<1运算结果也是0,那么在初始化数组的时候必然会报错,所以作为设计的安全性考虑,这里防止出现报错,选择了+2。
参考链接

总结:string和stringBuffer和stringbuilder的区别

  1. String 是字符串常量,当创建之后即不能更改。底层使用 final char value[]。
  2. StringBuffer 是字符串变量,可通过append()、insert()、setCharAt()等方法改变。底层使用 char[] value。是线程安全的,它的绝大多数方法都做了同步处理(被synchronized修饰,toString方法会进行对象缓存,减少元素复制开销。
  3. StringBuilder 与StringBuffer基本相似,都继承和实现了同样的接口和类。不同点在于:StringBuilder方法没使用synch修饰是线程不安全的,所以它比StringBuffer要快。toString方法直接返回一个新对象,不会进行对象缓存。

本文链接: http://www.dtmao.cc/news_show_630876.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?