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类的主要内容,如果未能解决你的问题,请参考以下文章

HashMap putVal 源码解析-JDK1.8

JDK1.8源码解析-HashMap

JDK源码及其他框架源码解析随笔地址导航

JDK源码之HashMap源码解析

追踪解析 jdk Proxy 源码

jdk下httpserver源码解析