StringBuffer 源码分析

StringBuffer继承了AbstractStringBuilder,我们主要来看下AbstractStringBuilder这个类:

AbstractStringBuilder

1)、成员

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

/**
* The count is the number of characters used.
*/
int count;

2)、方法

1、提供了两种构造器

AbstractStringBuilder() {
}

AbstractStringBuilder(int capacity) {
value = new char[capacity];
}

可以看出,第二种构造器可以在构造对象的时候就指定维护的数组的初始大小

2、扩容

public void ensureCapacity(int minimumCapacity) {
if (minimumCapacity > value.length) {
expandCapacity(minimumCapacity);
}
}

void expandCapacity(int minimumCapacity) {
int newCapacity = (value.length + 1) * 2;
if (newCapacity < 0) {
newCapacity = Integer.MAX_VALUE;
} else if (minimumCapacity > newCapacity) {
newCapacity = minimumCapacity;
}
value = Arrays.copyOf(value, newCapacity);
}

可以看出,如果维护的数组的长度不够,则会将长度变为原来的两倍

3、

public void trimToSize() {
if (count < value.length) {
value = Arrays.copyOf(value, count);
}
}

减少数组的长度到元素的个数

4、

public void setLength(int newLength) {
if (newLength < 0)
throw new StringIndexOutOfBoundsException(newLength);
if (newLength > value.length)
expandCapacity(newLength);

if (count < newLength) {
for (; count < newLength; count++)
value[count] = ‘\0‘;
} else {
count = newLength;
}
}

设置sequence长度

5、append方法

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

//本方法是StringBuffer append方法的核心,主要就是在扩容后,将append的字符串直接拷贝到扩容后的数组的相关位置上,并没有new其他不需要的对象

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

这里与String拼接字符串的方式做一下比较:

String在进行“+”拼接时,会new临时的StringBuffer对象,即  new StringBuilder().append(str).append("asjdkla").toString(),一旦在循环中做拼接字符串的操作,那么将会new大量StringBuffer和String(StringBuffer的toString方法会new String),导致开销极大

下面我们再看下String的concat方法

public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}

很明显,这种方式比使用“+”的方式好一些,但是还是new了多余的String对象,一旦在循环中调用,还是对性能有很大影响的
时间: 2024-10-14 19:49:58

StringBuffer 源码分析的相关文章

Java StringBuilder 和 StringBuffer 源码分析

简介 StringBuilder与StringBuffer是两个常用的操作字符串的类.大家都知道,StringBuilder是线程不安全的,而StringBuffer是线程安全的.前者是JDK1.5加入的,后者在JDK1.0就有了.下面分析一下它们的内部实现. 继承关系 public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence public

java.lang.StringBuffer源码分析

StringBuffer是一个线程安全的可变序列的字符数组对象,它与StringBuilder一样,继承父类AbstractStringBuilder.在多线程环境中,当方法操作是必须被同步,StringBuffer内的方法被同步化时,以实现跟在单线程中操作一样的一致性. public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence { //一

CharSequence,String ,Stringbuilder和StringBuffer源码分析

1.从类的定义看CharSequence.StringBuffer.StringBuilder.String的关系 下面先贴上这四者的定义(来自JDK1.6) CharSequence是一个定义字符串操作的接口,StringBuffer.StringBuilder.String中都实现了这个接口. //CharSequence定义 public interface CharSequence //StringBuffer定义 public final class StringBuffer exte

[源码]String StringBuffer StringBudlider(2)StringBuffer StringBuilder源码分析

纵骑横飞 章仕烜 昨天比较忙 今天把StringBuffer StringBulider的源码分析 献上 在讲 StringBuffer StringBuilder 之前 ,我们先看一下 它们共同的老祖宗 AbstractStringBuilder 这是 StringBuilder StringBuffer 的根基 再看看 这两个实现类 里边有什么 很显然,这两个东西什么都没写吧 我们看看 另一个门派的 String 看出 为什么 我们说String 对象是不可变的 StringBuilder

【源码】StringBuilder和StringBuffer源码深度剖析

//------------------------------------------------------------------------ 写篇博客不容易,请尊重作者劳动成果.转载请注明出处:http://blog.csdn.net/chdjj //------------------------------------------------------------------------ 我觉得要通过源码研究一个类,应该先从整体上了解这个类,比如说这个类的继承体系,有哪些超类,继承

AbstractCollection源码分析

AbstractCollection抽象类提供了Collection的骨架实现,Collection分析请看:http://blog.csdn.net/treeroot/admin/Referrers.aspx?EntryID=99591这里直接看它的代码是如何实现的.public abstract Iterator iterator();该方法没有实现.public abstract int size();该方法没有实现.public boolean isEmpty() { return si

Java源码分析——String的设计

Tip:笔者马上毕业了,准备开始Java的进阶学习计划.于是打算先从String类的源码分析入手,作为后面学习的案例.这篇文章寄托着今后进阶系列产出的愿望,希望能坚持下去,不忘初心,让自己保持那份对技术的热爱. 因为学习分析源码,所以借鉴了HollisChuang成神之路的大部分内容,并在此基础上对源码进行了学习,在此感谢. 问题的引入 关于String字符串,对于Java开发者而言,这无疑是一个非常熟悉的类.也正是因为经常使用,其内部代码的设计才值得被深究.所谓知其然,更得知其所以然. 举个例

BufferedReader源码分析之readLine方法

readLine方法是BufferedReader中一个非常常用的方法 使用它我们可以从一段输入流中一行一行的读数据 行的区分用"\r","\n"或者是"\r\n",下面就是BufferedReader中readLine的源代码 详细的分析都写在注释里了 String readLine(boolean ignoreLF) throws IOException { StringBuffer s = null; int startChar; sync

携程DynamicAPK插件化框架源码分析

携程DynamicAPK插件化框架源码分析 Author:莫川 插件核心思想 1.aapt的改造 分别对不同的插件项目分配不同的packageId,然后对各个插件的资源进行编译,生成R文件,然后与宿主项目的R文件进行id的合并. 要求:由于最终会将所有的资源文件id进行合并,因此,所有的资源名称均不能相同. 2.运行ClassLoader加载各Bundle 和MultiDex的思路是一样的,所有的插件都被加载到同一个ClassLoader当中,因此,不同插件中的Class必须保持包名和类名的唯一