java StringBuilder源码阅读
本文主要对StringBuilder源代码中的重点难点方法进行解析。
StringBuilder(String str) 创建一个新的StringBuilder,其初始内容为传入的字符串str
@HotSpotIntrinsicCandidate public StringBuilder(String str) { super(str); } AbstractStringBuilder(String str) { int length = str.length(); // 新创建的StringBuilder的长度为传入的字符串的长度+16 int capacity = (length < Integer.MAX_VALUE - 16) ? length + 16 : Integer.MAX_VALUE; final byte initCoder = str.coder(); coder = initCoder; value = (initCoder == LATIN1) ? new byte[capacity] : StringUTF16.newBytesFor(capacity); // 将str的内容append到StringBuilder后面 append(str); }
ensureCapacityInternal(int minimumCapacity) 确保StringBuilder内部的数组长度能够容纳至少minimumCapacity个字符
private void ensureCapacityInternal(int minimumCapacity) { // overflow-conscious code int oldCapacity = value.length >> coder; if (minimumCapacity - oldCapacity > 0) { value = Arrays.copyOf(value, newCapacity(minimumCapacity) << coder); } } // 生成新的数组长度(以字符为单位,如果一个字符对应多个bit则调用者自行左移) private int newCapacity(int minCapacity) { // overflow-conscious code int oldCapacity = value.length >> coder; // 默认新长度=旧长度*2+2 int newCapacity = (oldCapacity << 1) + 2; if (newCapacity - minCapacity < 0) { newCapacity = minCapacity; } // MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 // 由于MAX_ARRAY_SIZE代表的是字节长度,所以需要右移换算成字符长度 int SAFE_BOUND = MAX_ARRAY_SIZE >> coder; return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0) ? hugeCapacity(minCapacity) : newCapacity; } private int hugeCapacity(int minCapacity) { int SAFE_BOUND = MAX_ARRAY_SIZE >> coder; // SAFE_BOUND是安全界限,UNSAFE_BOUND是不安全界限 // 当minCapacity大于安全界限,小于等于不安全界限时返回minCapacity,勉强可用 // 但是如果minCapacity大于不安全,则目前虚拟机无法承载这么大的数组,报错 int UNSAFE_BOUND = Integer.MAX_VALUE >> coder; if (UNSAFE_BOUND - minCapacity < 0) { // overflow throw new OutOfMemoryError(); } return (minCapacity > SAFE_BOUND) ? minCapacity : SAFE_BOUND; }
AbstractStringBuilder::appendNull() 在StringBuilder后方加入'null'四个字符
private AbstractStringBuilder appendNull() { ensureCapacityInternal(count + 4); int count = this.count; byte[] val = this.value; if (isLatin1()) { val[count++] = 'n'; val[count++] = 'u'; val[count++] = 'l'; val[count++] = 'l'; } else { count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l'); } this.count = count; return this; }
StringBuilder::append(String str) 将str的内容接到StringBuilder后方
@Override @HotSpotIntrinsicCandidate public StringBuilder append(String str) { super.append(str); // 调用AbstractStringBuilder::append(String str) return this; } public AbstractStringBuilder append(String str) { if (str == null) { return appendNull(); } int len = str.length(); ensureCapacityInternal(count + len); putStringAt(count, str); count += len; return this; } private final void putStringAt(int index, String str) { if (getCoder() != str.coder()) { inflate(); } str.getBytes(value, index, coder); } // 如果当前StringBuilder的编码为Latin1编码,则把它转换成UTF16编码 // UTF16编码由于兼容Latin1编码所以没必要转换 // 例如,Latin1码元为0x1f ,转换成UTF16后码元为0x001f private void inflate() { if (!isLatin1()) { return; } byte[] buf = StringUTF16.newBytesFor(value.length); StringLatin1.inflate(value, 0, buf, 0, count); this.value = buf; this.coder = UTF16; }
StringBuilder::delete(int start, int end) 删除start和end之间的字符
@Override public StringBuilder delete(int start, int end) { super.delete(start, end); return this; } public AbstractStringBuilder delete(int start, int end) { int count = this.count; if (end > count) { end = count; } checkRangeSIOOBE(start, end, count); int len = end - start; if (len > 0) { // 左移 shift(end, -len); this.count = count - len; } return this; } // 检查start和end的合法性 private static void checkRangeSIOOBE(int start, int end, int len) { if (start < 0 || start > end || end > len) { throw new StringIndexOutOfBoundsException( "start " + start + ", end " + end + ", length " + len); } } private void shift(int offset, int n) { // 从offset处开始复制,每个元素向前移动n,共移动count-offset个元素 System.arraycopy(value, offset << coder, value, (offset + n) << coder, (count - offset) << coder); } /** * @param src 源数组 * @param srcPos 源数组复制起始点 * @param dest 目标数组 * @param destPos 目标数组复制起始点 * @param length 要复制的元素个数 */ public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
StringBuilder::replace(int start, int end, String str) 替换操作
@Override public StringBuilder replace(int start, int end, String str) { super.replace(start, end, str); return this; } public AbstractStringBuilder replace(int start, int end, String str) { int count = this.count; if (end > count) { end = count; } // 检查start、end的越界情况 checkRangeSIOOBE(start, end, count); int len = str.length(); // 获取新长度、确保新长度合法 int newCount = count + len - (end - start); ensureCapacityInternal(newCount); // 右移 shift(end, newCount - count); this.count = newCount; // 从start处将str的内容放入 putStringAt(start, str); return this; }

浙公网安备 33010602011771号