Java8 源码解析 AbstractStringBuilder

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8 源码解析 AbstractStringBuilder相关的知识,希望对你有一定的参考价值。

 

1 package java.lang;

 

1 // 抽象类AbstractStringBuilder实现了Appendable(可追加)、CharSequence(字符序列)接口
2 abstract class AbstractStringBuilder implements Appendable, CharSequence

 

1 // 字符数组
2 char[] value;

 

1 // 字符数量
2 int count;

 

1 // 该无参构造方法用于子类序列化
2 AbstractStringBuilder() {
3 }

 

1 // 包含容量参数的构造方法
2 AbstractStringBuilder(int capacity) {
3     value = new char[capacity];
4 }

 

1 // 获取字符数量
2 @Override
3 public int length() {
4     return count;
5 }

 

1 // 获取当前字符数组的容量
2 public int capacity() {
3     return value.length;
4 }

 

1 // 保证容量
2 public void ensureCapacity(int minimumCapacity) {
3     if (minimumCapacity > 0) // 如果最小容量>0
4         ensureCapacityInternal(minimumCapacity);
5 }

 

1 // 保证内部容量
2 private void ensureCapacityInternal(int minimumCapacity) {
3     // overflow-conscious code
4     if (minimumCapacity - value.length > 0) { // 如果最小容量>当前容量
5         // 创建当前字符数组内容对应的更大数组
6         value = Arrays.copyOf(value,
7                 newCapacity(minimumCapacity));
8     }
9 }

 

1 // 数组最大容量
2 private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

 

 1 // 更新容量,获取容量值
 2 private int newCapacity(int minCapacity) {
 3     // overflow-conscious code
 4     int newCapacity = (value.length << 1) + 2;
 5     if (newCapacity - minCapacity < 0) { // 如果新容量>最小容量
 6         newCapacity = minCapacity;
 7     }
 8     
 9     // newCapacity <= 0成立说明newCapacity已经溢出(>Integer.MAX_VALUE)
10     return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
11         ? hugeCapacity(minCapacity)
12         : newCapacity;
13 }

 

 1 // 处理超大容量 前提是minCapacity<=newCapacity
 2 private int hugeCapacity(int minCapacity) {
 3     // 保证容量不超过Integer.MAX_VALUE
 4     if (Integer.MAX_VALUE - minCapacity < 0) { // overflow
 5         throw new OutOfMemoryError();
 6     }
 7   
 8     // 折中方案,取中间值
 9     // 前提是newCapacity>MAX_ARRAY_SIZE,或者已经溢出
10     // minCapacity > MAX_ARRAY_SIZE成立说明最小需求是minCapacity
11     // minCapacity <= MAX_ARRAY_SIZE成立说明最小需求是MAX_ARRAY_SIZE
12     return (minCapacity > MAX_ARRAY_SIZE)
13         ? minCapacity : MAX_ARRAY_SIZE;
14 }

 

1 // 把数组长度削减到最小
2 public void trimToSize() {
3     if (count < value.length) {
4         value = Arrays.copyOf(value, count);
5     }
6 }

 

 1 // 字符数量达到新长度
 2 public void setLength(int newLength) {
 3     if (newLength < 0) // 如果新长度<0
 4         throw new StringIndexOutOfBoundsException(newLength);
 5     ensureCapacityInternal(newLength); // 保证内部容量
 6 
 7     if (count < newLength) { // 如果字符数量<新长度,则用‘\0‘字符补充
 8         Arrays.fill(value, count, newLength, ‘\0‘);
 9     }
10     
11     // 更新字符数量
12     count = newLength;
13 }

 

1 // 根据下标获取单个字符
2 @Override
3 public char charAt(int index) {
4     if ((index < 0) || (index >= count)) // 如果下标非法
5         throw new StringIndexOutOfBoundsException(index);
6     return value[index];
7 }

 

 1 // 获取子串,把它拷贝到目标字符数组
 2 public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
 3 {
 4     if (srcBegin < 0) // 如果源数组开始位置<0
 5         throw new StringIndexOutOfBoundsException(srcBegin);
 6     if ((srcEnd < 0) || (srcEnd > count)) // 如果源数组结束位置非法
 7         throw new StringIndexOutOfBoundsException(srcEnd);
 8     if (srcBegin > srcEnd) // 如果源数组开始位置>源数组结束位置
 9         throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
10     System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
11 }

 

1 // 根据下标,修改单个字符
2 public void setCharAt(int index, char ch) {
3     if ((index < 0) || (index >= count)) // 如果下标非法
4         throw new StringIndexOutOfBoundsException(index);
5     value[index] = ch;
6 }

 

1 // 末尾追加Object对象
2 public AbstractStringBuilder append(Object obj) {
3     return append(String.valueOf(obj));
4 }

 

 1 // 末尾追加String对象
 2 public AbstractStringBuilder append(String str) {
 3     if (str == null) // 如果str为空
 4         return appendNull();
 5     int len = str.length();
 6     ensureCapacityInternal(count + len); // 保证内部容量
 7     str.getChars(0, len, value, count); // 拷贝字符
 8     count += len; // 更新字符数量
 9     return this;
10 }

 

 1 // 末尾追加AbstractStringBuilder引用指向的对象
 2 AbstractStringBuilder append(AbstractStringBuilder asb) {
 3     if (asb == null) // 如果当前引用指向的对象为空
 4         return appendNull();
 5     int len = asb.length();
 6     ensureCapacityInternal(count + len); // 保证内部容量
 7     asb.getChars(0, len, value, count); // 拷贝字符
 8     count += len; // 更新字符数量
 9     return this;
10 }

 

 1 @Override
 2 // 末尾追加CharSequence引用指向的对象
 3 public AbstractStringBuilder append(CharSequence s) {
 4     if (s == null) // 如果当前引用指向的对象为空
 5         return appendNull();
 6     if (s instanceof String) // 如果当前引用指向的是String对象
 7         return this.append((String)s);
 8     if (s instanceof AbstractStringBuilder) // 如果当前引用指向的是AbstractStringBuilder
 9         return this.append((AbstractStringBuilder)s);
10 
11     return this.append(s, 0, s.length());
12 }

 

 1 // 末尾追加null
 2 private AbstractStringBuilder appendNull() {
 3     int c = count;
 4     ensureCapacityInternal(c + 4); // 保证内部容量
 5     final char[] value = this.value;
 6     value[c++] = ‘n‘;
 7     value[c++] = ‘u‘;
 8     value[c++] = ‘l‘;
 9     value[c++] = ‘l‘;
10     count = c; // 更新字符数量
11     return this;
12 }

 

 1 // 末尾追加CharSequence子串
 2 @Override
 3 public AbstractStringBuilder append(CharSequence s, int start, int end) {
 4     if (s == null) // 如果字符序列引用为空
 5         s = "null";
 6     if ((start < 0) || (start > end) || (end > s.length())) // 如果开始位置或结束位置非法
 7         throw new IndexOutOfBoundsException(
 8             "start " + start + ", end " + end + ", s.length() "
 9             + s.length());
10     int len = end - start; // 获取子串长度
11     ensureCapacityInternal(count + len); // 保证内部容量
12     for (int i = start, j = count; i < end; i++, j++) // 每次循环追加一个字符
13         value[j] = s.charAt(i);
14     count += len; // 更新字符数量
15     return this;
16 }

 

1 // 末尾追加字符数组
2 public AbstractStringBuilder append(char[] str) {
3     int len = str.length; // 获取字符数组长度
4     ensureCapacityInternal(count + len); // 保证内部容量
5     System.arraycopy(str, 0, value, count, len); // 拷贝字符
6     count += len; // 更新字符数量
7     return this;
8 }

 

1 // 末尾追加字符数组子串
2 public AbstractStringBuilder append(char str[], int offset, int len) {
3     // 如果子串长度>0
4     if (len > 0)                // let arraycopy report AIOOBE for len < 0
5         ensureCapacityInternal(count + len); // 保证内部容量
6     System.arraycopy(str, offset, value, count, len); // 拷贝字符
7     count += len; // 更新字符数量
8     return this;
9 }

 

 1 // 末尾追加布尔类型变量
 2 public AbstractStringBuilder append(boolean b) {
 3     if (b) { // 如果追加的内容是true
 4         ensureCapacityInternal(count + 4); // 保证内部容量
 5         // 追加"true"
 6         value[count++] = ‘t‘;
 7         value[count++] = ‘r‘;
 8         value[count++] = ‘u‘;
 9         value[count++] = ‘e‘;
10     } else { // 如果追加的内容是false
11         ensureCapacityInternal(count + 5); // 保证内部容量
12         // 追加"false"
13         value[count++] = ‘f‘;
14         value[count++] = ‘a‘;
15         value[count++] = ‘l‘;
16         value[count++] = ‘s‘;
17         value[count++] = ‘e‘;
18     }
19     return this;
20 }

 

1 // 末尾追加单个字符
2 @Override
3 public AbstractStringBuilder append(char c) {
4     ensureCapacityInternal(count + 1); // 保证内部容量
5     value[count++] = c; // 追加单个字符
6     return this;
7 }

 

 1 // 末尾追加整型变量值
 2 public AbstractStringBuilder append(int i) {
 3     if (i == Integer.MIN_VALUE) { // 如果i是整型里面的最小值
 4         append("-2147483648");
 5         return this;
 6     }
 7     // 获取整型变量值长度
 8     int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
 9                                  : Integer.stringSize(i);
10     int spaceNeeded = count + appendedLength;
11     ensureCapacityInternal(spaceNeeded); // 保证内部容量
12     Integer.getChars(i, spaceNeeded, value); // 拷贝字符
13     count = spaceNeeded; // 更新字符数量
14     return this;
15 }

 

 1 // 末尾追加长整型变量值
 2 public AbstractStringBuilder append(long l) {
 3     if (l == Long.MIN_VALUE) { // 如果i是长整型里面的最小值
 4         append("-9223372036854775808");
 5         return this;
 6     }
 7     // 获取长整型变量值长度
 8     int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
 9                                  : Long.stringSize(l);
10     int spaceNeeded = count + appendedLength;
11     ensureCapacityInternal(spaceNeeded); // 保证内部容量
12     Long.getChars(l, spaceNeeded, value); // 拷贝字符
13     count = spaceNeeded; // 更新字符数量
14     return this;
15 }

 

1 // 末尾追加浮点型变量值
2 public AbstractStringBuilder append(float f) {
3     FloatingDecimal.appendTo(f,this);
4     return this;
5 }

 

1 // 末尾追加双精度型变量值
2 public AbstractStringBuilder append(double d) {
3     FloatingDecimal.appendTo(d,this);
4     return this;
5 }

 

 1 // 删除子串
 2 public AbstractStringBuilder delete(int start, int end) {
 3     if (start < 0) // 如果开始位置<0
 4         throw new StringIndexOutOfBoundsException(start);
 5     if (end > count) // 如果结束位置>count
 6         end = count;
 7     if (start > end) // 如果开始位置>结束位置
 8         throw new StringIndexOutOfBoundsException();
 9     int len = end - start;
10     if (len > 0) { // 如果子串长度>0
11         System.arraycopy(value, start+len, value, start, count-end); // 拷贝字符
12         count -= len; // 更新字符数量
13     }
14     return this;
15 }

 

1 // 根据下标,删除单个字符
2 public AbstractStringBuilder deleteCharAt(int index) {
3     if ((index < 0) || (index >= count)) // 如果下标非法
4         throw new StringIndexOutOfBoundsException(index);
5     System.arraycopy(value, index+1, value, index, count-index-1); // 拷贝字符
6     count--; // 更新字符数量
7     return this;
8 }

 

 1 // 用字符串替换一个区间内的所有字符
 2 public AbstractStringBuilder replace(int start, int end, String str) {
 3     if (start < 0) // 如果开始位置<0
 4         throw new StringIndexOutOfBoundsException(start);
 5     if (start > count) // 如果开始位置>字符数量
 6         throw new StringIndexOutOfBoundsException("start > length()");
 7     if (start > end) // 如果开始位置>结束位置
 8         throw new StringIndexOutOfBoundsException("start > end");
 9     
10     // 如果结束位置>字符数量
11     if (end > count)
12         end = count;
13     int len = str.length(); // 获取字符串长度
14     int newCount = count + len - (end - start); // 获取新的字符数量
15     ensureCapacityInternal(newCount); // 保证内部容量
16 
17     // 把结束位置后面的字符移动到开始位置+字符串长度这一位置后面
18     System.arraycopy(value, end, value, start + len, count - end); 
19     str.getChars(value, start); // 拷贝字符串
20     count = newCount; // 更新字符数量
21     return this;
22 }

 

1 // 获取子串,返回String对象的引用
2 public String substring(int start) {
3     return substring(start, count);
4 }

 

1 // 获取子串,返回CharSequence引用
2 @Override
3 public CharSequence subSequence(int start, int end) {
4     return substring(start, end);
5 }

 

 1 // 获取子串,返回String对象的引用
 2 public String substring(int start, int end) {
 3     if (start < 0) // 如果开始位置<0
 4         throw new StringIndexOutOfBoundsException(start);
 5     if (end > count) // 如果结束位置>count
 6         throw new StringIndexOutOfBoundsException(end);
 7     if (start > end) // 如果开始位置>结束位置
 8         throw new StringIndexOutOfBoundsException(end - start);
 9     // 返回String对象的引用
10     return new String(value, start, end - start);
11 }

 

 1 // 插入字符串
 2 public AbstractStringBuilder insert(int index, char[] str, int offset,
 3                                     int len)
 4 {
 5     if ((index < 0) || (index > length())) // 如果插入位置非法
 6         throw new StringIndexOutOfBoundsException(index);
 7     // 如果字符数组起始位置或插入的字符串长度非法
 8     if ((offset < 0) || (len < 0) || (offset > str.length - len)) 
 9         throw new StringIndexOutOfBoundsException(
10             "offset " + offset + ", len " + len + ", str.length "
11             + str.length);
12     ensureCapacityInternal(count + len); // 保证内部容量
13     // 右移
14     System.arraycopy(value, index, value, index + len, count - index);
15     // 插入字符串
16     System.arraycopy(str, offset, value, index, len);
17     count += len; // 更新字符数量
18     return this;
19 }

 

1 // 插入Object对象
2 public AbstractStringBuilder insert(int offset, Object obj) {
3     return insert(offset, String.valueOf(obj));
4 }

 

 1 // 插入String对象
 2 public AbstractStringBuilder insert(int offset, String str) {
 3     if ((offset < 0) || (offset > length())) // 如果开始位置非法
 4         throw new StringIndexOutOfBoundsException(offset);
 5     if (str == null) // 如果String引用指向的对象为空
 6         str = "null";
 7     int len = str.length();
 8     ensureCapacityInternal(count + len); // 保证内部容量
 9     System.arraycopy(value, offset, value, offset + len, count - offset); // 右移
10     str.getChars(value, offset); // 插入字符串
11     count += len; // 更新字符数量
12     return this;
13 }

 

 1 // 插入字符数组
 2 public AbstractStringBuilder insert(int offset, char[] str) {
 3     if ((offset < 0) || (offset > length())) // 如果开始位置非法
 4         throw new StringIndexOutOfBoundsException(offset);
 5     int len = str.length;
 6     ensureCapacityInternal(count + len); // 保证内部容量
 7     System.arraycopy(value, offset, value, offset + len, count - offset); // 右移
 8     System.arraycopy(str, 0, value, offset, len); // 插入字符串
 9     count += len; // 更新字符数量
10     return this;
11 }

 

1 // 插入字符序列
2 public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
3     if (s == null) // 如果字符序列引用指向的对象为空
4         s = "null";
5     if (s instanceof String) // 如果字符序列引用指向的是String对象
6         return this.insert(dstOffset, (String)s);
7     return this.insert(dstOffset, s, 0, s.length());
8 }

 

 1 // 插入字符序列
 2  public AbstractStringBuilder insert(int dstOffset, CharSequence s,
 3                                      int start, int end) {
 4     if (s == null) // 如果字符序列引用指向的对象为空
 5         s = "null";
 6     if ((dstOffset < 0) || (dstOffset > this.length())) // 如果插入位置非法
 7         throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
 8     // 如果开始位置或结束位置非法
 9     if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
10         throw new IndexOutOfBoundsException(
11             "start " + start + ", end " + end + ", s.length() "
12             + s.length());
13     int len = end - start; // 获取插入的字符串长度
14     ensureCapacityInternal(count + len); // 保证内部容量
15     // 右移
16     System.arraycopy(value, dstOffset, value, dstOffset + len,
17                      count - dstOffset);
18     // 每次循环插入单个字符
19     for (int i=start; i<end; i++)
20         value[dstOffset++] = s.charAt(i);
21     count += len; // 更新字符数量
22     return this;
23 }

 

1 // 插入布尔类型变量值
2 public AbstractStringBuilder insert(int offset, boolean b) {
3     return insert(offset, String.valueOf(b));
4 }

 

 1 // 插入单个字符
 2 public AbstractStringBuilder insert(int offset, char c) {
 3     ensureCapacityInternal(count + 1); // 保证内部容量
 4     // 右移
 5     System.arraycopy(value, offset, value, offset + 1, count - offset);
 6     // 插入单个字符
 7     value[offset] = c;
 8     count += 1; // 更新字符数量
 9     return this;
10 }

 

1 // 插入整型变量值
2 public AbstractStringBuilder insert(int offset, int i) {
3     return insert(offset, String.valueOf(i));
4 }

 

1 // 插入长整型变量值
2 public AbstractStringBuilder insert(int offset, long l) {
3     return insert(offset, String.valueOf(l));
4 }

 

1 // 插入浮点型变量值
2 public AbstractStringBuilder insert(int offset, float f) {
3     return insert(offset, String.valueOf(f));
4 }

 

1 // 插入双精度变量值
2 public AbstractStringBuilder insert(int offset, double d) {
3     return insert(offset, String.valueOf(d));
4 }

 

1 // 获取子串顺序下首次出现的位置
2 public int indexOf(String str) {
3     return indexOf(str, 0);
4 }

 

1 // 获取子串顺序下首次出现的位置
2 public int indexOf(String str, int fromIndex) {
3     return String.indexOf(value, 0, count, str, fromIndex);
4 }

 

1 // 获取子串逆序下首次出现的位置
2 public int lastIndexOf(String str) {
3     return lastIndexOf(str, count);
4 }

 

1 // 获取子串逆序下首次出现的位置
2 public int lastIndexOf(String str, int fromIndex) {
3     return String.lastIndexOf(value, 0, count, str, fromIndex);
4 }

 

 1 // 反转
 2 public AbstractStringBuilder reverse() {
 3     boolean hasSurrogates = false;
 4     int n = count - 1;
 5     // 折半交换
 6     // 如果存在奇数个字符,则跳过中间字符
 7     for (int j = (n-1) >> 1; j >= 0; j--) {
 8         int k = n - j;
 9         // 交换
10         char cj = value[j];
11         char ck = value[k];
12         value[j] = ck;
13         value[k] = cj;
14         if (Character.isSurrogate(cj) ||
15             Character.isSurrogate(ck)) {
16             hasSurrogates = true;
17         }
18     }
19     if (hasSurrogates) {
20         reverseAllValidSurrogatePairs();
21     }
22     return this;
23 }
24 
25 /** Outlined helper method for reverse() */
26 private void reverseAllValidSurrogatePairs() {
27     for (int i = 0; i < count - 1; i++) {
28         char c2 = value[i];
29         if (Character.isLowSurrogate(c2)) {
30             char c1 = value[i + 1];
31             if (Character.isHighSurrogate(c1)) {
32                 value[i++] = c1;
33                 value[i] = c2;
34             }
35         }
36     }
37 }

 

1 // toString抽象方法
2 @Override
3 public abstract String toString();

 

1 // 获取字符数组
2 final char[] getValue() {
3     return value;
4 }

 

以上是关于Java8 源码解析 AbstractStringBuilder的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLocal源码解析-Java8

Java8 源码解析 StringBuilder

ArrayList源码解析-Java8

Java8 源码解析 数组拷贝

Java面试3——Java8List源码解析

关于Java8 stream的相关使用及解析