jdk源码解析--AbstractStringBuilder类
Posted 我的IT技术路
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdk源码解析--AbstractStringBuilder类相关的知识,希望对你有一定的参考价值。
与String相关的两个类是StringBuilder 和StringBuffer。这两个类都是基于一个父类AbstractStringBuilder。现在可以看下这个类的具体实现。
1. 基本定义:
1. abstract class AbstractStringBuilder implements Appendable, CharSequence {
2. char[] value;//具体字符数组
3. int count;//数组的长度
4. }
是一个抽象类,包含两个成员变量,value存入具体的值,count 长度
2. 构造函数:两个,一个无参,一个确定长度
1. AbstractStringBuilder() {//无参构造
2. }
3. AbstractStringBuilder(int capacity) {//构造一个长度大小确定的类
4. value = new char[capacity];
5. }
3. 具体函数功能:
比较简单的几个函数功能(length/capacity/getValue)就不用介绍了,可以自己看下源码。下面重点解读以下函数:
3.1 确保容量足够:传入一个最小的容量值,确保容量足够,不足时进行扩容
1. public void ensureCapacity(int minimumCapacity) {
2. if (minimumCapacity > 0)
3. ensureCapacityInternal(minimumCapacity);
4. }
5. private void ensureCapacityInternal(int minimumCapacity) {
6. // overflow-conscious code当不足时,进行扩容
7. if (minimumCapacity - value.length > 0)
8. expandCapacity(minimumCapacity);
9. }
10. void expandCapacity(int minimumCapacity) {
11. int newCapacity = value.length * 2 + 2; //将容量进行两倍+2扩容
12. if (newCapacity - minimumCapacity < 0) //扩充后依然不够,直接将容量设置 为传入值
13. newCapacity = minimumCapacity;
14. if (newCapacity < 0) {
15. if (minimumCapacity < 0) // overflow
16. throw new OutOfMemoryError();
17. newCapacity = Integer.MAX_VALUE;
18. }
19. value = Arrays.copyOf(value, newCapacity); //扩容后,进行数据拷贝
20. }
3.2 截取长度大小的值
1. public void trimToSize() {
2. if (count < value.length) { //如果数组的长度大于count
3. value = Arrays.copyOf(value, count); //返回count长度的数组
4. }
5. }
3.3 更新长度
1. public void setLength(int newLength) {
2. if (newLength < 0)
3. throw new StringIndexOutOfBoundsException(newLength);
4. ensureCapacityInternal(newLength);//扩容
5.
6. if (count < newLength) {
7. Arrays.fill(value, count, newLength, '\0');//多余的赋值0
8. }
9.
10. count = newLength;
11. }
3.4 获取值相关的函数
1. public char charAt(int index) {
2. if ((index < 0) || (index >= count))
3. throw new StringIndexOutOfBoundsException(index);
4. return value[index];//返回index对应的值
5. }
3.5 字符拷贝
1. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
2. {
3. if (srcBegin < 0)
4. throw new StringIndexOutOfBoundsException(srcBegin);
5. if ((srcEnd < 0) || (srcEnd > count))
6. throw new StringIndexOutOfBoundsException(srcEnd);
7. if (srcBegin > srcEnd)
8. throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
9. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);//调用系统数组拷贝进行
10. }
3.6 将某个位置设值
1. public void setCharAt(int index, char ch) {
2. if ((index < 0) || (index >= count))
3. throw new StringIndexOutOfBoundsException(index);
4. value[index] = ch;
5. }
3.7 字符拼接
1. public AbstractStringBuilder append(String str) {
2. if (str == null)
3. return appendNull();
4. int len = str.length();
5. ensureCapacityInternal(count + len);//确保长度
6. str.getChars(0, len, value, count);//将新的数组进行赋值
7. count += len;//更新长度
8. return this;
9. }
3.8 字符删除
1. public AbstractStringBuilder delete(int start, int end) {
2. if (start < 0)
3. throw new StringIndexOutOfBoundsException(start);
4. if (end > count)
5. end = count;
6. if (start > end)
7. throw new StringIndexOutOfBoundsException();
8. int len = end - start;
9. if (len > 0) {
10. System.arraycopy(value, start+len, value, start, count-end);//更新字符数组
11. count -= len;//更新数组长度
12. }
13. return this;
14. }
3.9 字符替换
1. public AbstractStringBuilder replace(int start, int end, String str) {
2. if (start < 0)
3. throw new StringIndexOutOfBoundsException(start);
4. if (start > count)
5. throw new StringIndexOutOfBoundsException("start > length()");
6. if (start > end)
7. throw new StringIndexOutOfBoundsException("start > end");
8. //字符校验
9. if (end > count)
10. end = count;
11. int len = str.length();
12. int newCount = count + len - (end - start);
13. ensureCapacityInternal(newCount);//确保字符长度
14.
15. System.arraycopy(value, end, value, start + len, count - end);//更新字符数组
16. str.getChars(value, start);//将str拷贝到字符数组中
17. count = newCount;//更新新的长度
18. return this;
19. }
3.10 返回子串
1. public String substring(int start, int end) {
2. if (start < 0)
3. throw new StringIndexOutOfBoundsException(start);
4. if (end > count)
5. throw new StringIndexOutOfBoundsException(end);
6. if (start > end)
7. throw new StringIndexOutOfBoundsException(end - start);
8. return new String(value, start, end - start); //返回一个新的字符串
9. }
3.11 插入
1. public AbstractStringBuilder insert(int offset, String str) {
2. if ((offset < 0) || (offset > length()))
3. throw new StringIndexOutOfBoundsException(offset);
4. if (str == null)
5. str = "null";
6. int len = str.length();
7. ensureCapacityInternal(count + len); //容量确保
8. System.arraycopy(value, offset, value, offset + len, count - offset;//系统拷贝
9. str.getChars(value, offset); //将str拷贝进去
10. count += len; //更新长度
11. return this;
12. }
3.12 定位
1. public int indexOf(String str, int fromIndex) {
2. return String.indexOf(value, 0, count, str, fromIndex); //参考字符串的定位函数
3. }
3.13 字符反转
1. public AbstractStringBuilder reverse() {
2. boolean hasSurrogates = false;
3. int n = count - 1;
4. for (int j = (n-1) >> 1; j >= 0; j--) {//取一半的数据
5. int k = n - j;
6. char cj = value[j];
7. char ck = value[k];
8. value[j] = ck;
9. value[k] = cj;//这几部是完成交换
10. if (Character.isSurrogate(cj) ||
11. Character.isSurrogate(ck)) {//如果是增加字符
12. hasSurrogates = true;
13. }
14. }
15. if (hasSurrogates) {
16. reverseAllValidSurrogatePairs();//调用调整函数进行调整
17. }
18. return this;
19. }
20. //将一对增量字符进行交换
21. private void reverseAllValidSurrogatePairs() {
22. for (int i = 0; i < count - 1; i++) {
23. char c2 = value[i];
24. if (Character.isLowSurrogate(c2)) {//如果是增加字符,进行调整
25. char c1 = value[i + 1];
26. if (Character.isHighSurrogate(c1)) {
27. value[i++] = c1;
28. value[i] = c2;
29. }
30. }
31. }
32. }
以上是关于jdk源码解析--AbstractStringBuilder类的主要内容,如果未能解决你的问题,请参考以下文章