StringBuilder
StringBuilder是可变字符串类型,它被人所熟知的功能就是可以很方便的对字符串进行拼接、构造:
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence
方法是 final的,继承了 AbstractStringBuilder抽象类:
abstract class AbstractStringBuilder implements Appendable, CharSequence { char[] value; int count; ... }
可以看到它实现了 Appendable接口,而 Appendable接口就是提供了可以被添加char序列和值的功能,它实现了三种 append方法:
Appendable append(CharSequence csq) throws IOException; Appendable append(CharSequence csq, int start, int end) throws IOException; Appendable append(char c) throws IOException;
其中 CharSequence是 char值的可读序列,此接口对许多不同种类的 char 序列提供统一的只读访问, String StringBuilder StringBuffer都实现了这个接口:
int length(); char charAt(int index); CharSequence subSequence(int start, int end);
在 AbstractStringBuilder抽象类中,提供了一系列的 append和 insert方法的实现,下面是其中一种实现:
public AbstractStringBuilder append(String str) { if (str == null) str = "null"; //如果为空,则添加null字符串 int len = str.length(); ensureCapacityInternal(count + len);//保证容量 //复制str字符串到char数组value,从count位开始添加 str.getChars(0, len, value, count); count += len; return this; }
private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code if (minimumCapacity - value.length > 0) expandCapacity(minimumCapacity); }
如果传递的最小容量大于现有容量,则必须进行扩容:
void expandCapacity(int minimumCapacity) { //新容量为old*2+2 int newCapacity = value.length * 2 + 2; if (newCapacity - minimumCapacity < 0) newCapacity = minimumCapacity; if (newCapacity < 0) { if (minimumCapacity < 0) // overflow throw new OutOfMemoryError(); newCapacity = Integer.MAX_VALUE; } value = Arrays.copyOf(value, newCapacity); }
注意: AbstractStringBuilder中的方法实现都没有进行同步
insert方法:
public AbstractStringBuilder insert(int offset, String str) { if ((offset < 0) || (offset > length())) throw new StringIndexOutOfBoundsException(offset); if (str == null) str = "null"; int len = str.length(); ensureCapacityInternal(count + len); System.arraycopy(value, offset, value, offset + len, count - offset); str.getChars(value, offset); count += len; return this; }StringBuffer
StringBuffer类的出现实际上比 StringBuilder要早,当初提供 StringBuilder类只是为了提供一个单个线程使用的 StringBuffer等价类。如果观察 StringBuffer的源代码,可以发现它的方法和 StringBuilder相同,只不过都加上了 synchronized ,比如:
public synchronized StringBuffer append(String str) { super.append(str); return this; }StringBuilder vs StringBuffer
现在我们已经明确的记住了 StringBuffer是线程安全的,而 StringBuilder不是
在效率上, StringBuffer因为对方法做了同步,所以一般是低于 StringBuilder的
二者都是可变的,因为二者都继承 AbstractStringBuilder,它的 char[] value 没有使用 final修饰,只是普通数组。 String的 value是 final的,即不可变的
都有实现 CharSequence接口
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/64430.html
摘要:当然大多数情况下就是我们是在单线程下进行的操作,所以大多数情况下是建议用而不用的,就是速度的原因。 第三阶段 JAVA常见对象的学习 StringBuffer和StringBuilder类 (一) StringBuffer类的概述 (1) 基本概述 下文以StringBuffer为例 前面我们用字符串做拼接,比较耗时并且也耗内存(每次都会构造一个新的string对象),而这种拼接操作又...
摘要:和它们都是可变的字符串,不过它们之间的区别是初中级面试出现几率十分高的一道题。区别线程安全线程安全,线程不安全。区别性能既然是线程安全的,它的所有公开方法都是同步的,是没有对方法加锁同步的,所以毫无疑问,的性能要远大于。 StringBuffer 和 StringBuilder 它们都是可变的字符串,不过它们之间的区别是 Java 初中级面试出现几率十分高的一道题。这么简单的一道题,栈...
摘要:测试拼接速度测试的结果在循环中,拼接字符串的速度远低于和利用查看字节码文件,寻找其中的差异命令行执行结果可以看出,拼接的时候也是通过的方法进行拼接的产生差异的原因是,在每次循环中,拼接的时候都了一个是线程安全的,只比稍慢了一点若不是 String、StringBuilder、StringBuffer 测试拼接速度 @Test public void testString() { ...
摘要:不指定容量会显著降低性能一般使用在方法内部来完成类似功能,因为是线程不安全的,所以用完以后可以丢弃。主要用在全局变量中相同情况下使用相比使用仅能获得左右的性能提升,但却要冒多线程不安全的风险。 String 作为最基础的引用数据类型,日常的开发中被大量的使用。基于不可变的特性,一旦被过度地使用,堆内存就会负荷不堪,甚至影响性能,为此,Java 设计者特意为 String 在方法区中开辟...
摘要:是线程安全的,很多方法都是方法,而不是线程安全的,但其在单线程程序中的性能比要高。和类的区别也在于此,新引入的类不是线程安全的,但其在单线程中的性能比高。 这两个类从功能上来讲,几乎没有任何差别。 1.StringBuilder 首先,String类是不可变类,所以,任何对String的改变都会引发新的String对象的生成;新引入的StringBuilder类不是线程安全的.因为,H...
摘要:如果对于经常改变内容的字符串,使用效率高,但是它只适用于单线程的场景,在多线程场景下,容易导致数据不一致的现象出现。多线程场景下,要使用。在大部分情况下,线程安全的可变字符序列。可将字符串缓冲区安全地用于多个线程。 本人博客 http://www.cnblogs.com/runfor... 总结: 1.String是字符串常量,StringBuffer是线程安全的字符串变量,Stri...
阅读 1575·2021-11-02 14:48
阅读 3619·2019-08-30 15:56
阅读 2740·2019-08-30 15:53
阅读 3183·2019-08-30 14:09
阅读 3064·2019-08-30 12:59
阅读 2823·2019-08-29 18:38
阅读 2641·2019-08-26 11:41
阅读 2173·2019-08-23 16:45