源码阅读:为什么用StringBuilder
前言:平时在工作中一直强调,当对字符串进行拼接时,字符拼接次数超过二次,就一定要使用StringBuilder,最近装了JD,可以很容易看到源码,就来看看到底StringBuilder有什么好处。
类结构:先来看看StringBuilder实现/继承了哪些接口/类
StringBuilder | -CharSequence<<>> | |
-Serializable<<>> | ||
-AbstractStringBuilder | -Appendable<<>> | |
-CharSequence<<>> |
阅读:
StringBuffer有四个构造器:
StringBuffer sb = new StringBuffer(); // 默认构造器,初始化char数组长度为16 sb = new StringBuffer(10); // 初始化char数组长度为固定长度 sb = new StringBuffer("TestString"); // 初始化char数组长度为字符串长度+16 sb = new StringBuffer(sb); // 初始化char数组长度为sb长度+16
StringBuffer在真正操作的时候使用的是char数组,默认构造器char数组长度为16,而toString的时候返回的是一个字符串:
return new String(this.value, 0, this.count);
在工作中用到最多的就是StringBuilder.append(),看看append时是怎么操作的:
public AbstractStringBuilder append(String paramString) { if (paramString == null) paramString = "null"; int i = paramString.length(); if (i == 0) return this; int j = this.count + i; if (j > this.value.length) // 当加起来的字符长度超过当前限定的长度时就增大数组的长度 expandCapacity(j); paramString.getChars(0, i, this.value, this.count); // 再对数据进行存储,使用了System.arrayCopy this.count = j; return this; }
void expandCapacity(int paramInt) { int i = (this.value.length + 1) * 2; // 长度+1并double一下 if (i < 0) i = 2147483647; else if (paramInt > i) { i = paramInt; } char[] arrayOfChar = new char[i]; System.arraycopy(this.value, 0, arrayOfChar, 0, this.count); // 将已有数据复制到新数组里 this.value = arrayOfChar; }
最终对数据进行汇总的是使用的System.arraycopy,关于这个方法只能跟踪到以下代码:
public static native void arraycopy(Object paramObject1, int paramInt1, Object paramObject2, int paramInt2, int paramInt3);
native意思是调用到本地代码,即jvm,dll之类的JVM内核文件里的代码,具体实现过程还有待进一步研究,更进一步说明了System.arraycopy的好处,以后数组拷贝都使用这个方法。
路慢慢其休远羲,吾将上下而求所