首页 > 代码库 > java之AbstractStringBuilder类详解
java之AbstractStringBuilder类详解
目录 | |
AbstractStringBuilder类 | |
字段 | |
构造器 | |
方法 | |
public abstract String toString() | |
扩充容量 | void expandCapacity(int minimumCapacity) |
public int length() | |
public int capacity() | |
public void ensureCapacity(int minimumCapacity) | |
反转 | public AbstractStringBuilder reverse() |
添加 | public AbstractStringBuilder append(String str) public AbstractStringBuilder append(StringBuffer sb) public AbstractStringBuilder append(Object obj) public AbstractStringBuilder append(CharSequence s) public AbstractStringBuilder append(CharSequence s, int start, int end) public AbstractStringBuilder append(char str[]) public AbstractStringBuilder append(char str[], int offset, int len) public AbstractStringBuilder append(boolean b) public AbstractStringBuilder append(char c) public AbstractStringBuilder append(int i) public AbstractStringBuilder append(long l) public AbstractStringBuilder append(float f) public AbstractStringBuilder append(double d) |
删除 | public AbstractStringBuilder delete(int start, int end) |
插入 | public AbstractStringBuilder insert(int offset, String str) public AbstractStringBuilder insert(int offset, Object obj) public AbstractStringBuilder insert(int offset, boolean b) public AbstractStringBuilder insert(int offset, int i) public AbstractStringBuilder insert(int offset, long l) public AbstractStringBuilder insert(int offset, float f) public AbstractStringBuilder insert(int offset, double d) public AbstractStringBuilder insert(int offset, char c) public AbstractStringBuilder insert(int offset, char str[]) public AbstractStringBuilder insert(int dstOffset, CharSequence s) public AbstractStringBuilder insert(int index, char str[], int offset,int len) public AbstractStringBuilder insert(int dstOffset, CharSequence s,int start, int end) |
替换 | public AbstractStringBuilder replace(int start, int end, String str) |
获取子序列 | public String substring(int start, int end) public String substring(int start) public CharSequence subSequence(int start, int end) |
调整空间 | public void trimToSize() |
设置长度 | public void setLength(int newLength) |
获取字符 | public char charAt(int index) |
修改字符 | public void setCharAt(int index, char ch) |
删除字符 | public AbstractStringBuilder deleteCharAt(int index) |
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) | |
public int codePointAt(int index) | |
public int codePointBefore(int index) | |
public int codePointCount(int beginIndex, int endIndex) | |
public int offsetByCodePoints(int index, int codePointOffset) | |
public AbstractStringBuilder appendCodePoint(int codePoint) |
AbstractStringBuilder类 |
位置:java.lang包中 |
声明: abstract class AbstractStringBuilderimplements Appendable, CharSequence |
AbstractStringBuilder 类有abstract 修饰,可知它不能被实例化。 AbstractStringBuilder 类有两个子类:StringBuilder和StringBuffer。 |
字段 |
/** * The value is used for character storage. */ char value[]; /** * The count is the number of characters used. */ int count; |
构造器 |
1、无参构造器 AbstractStringBuilder() { } |
2、创建abstractstringbuilder实现类的对象时指定缓冲区大小为capacity。 AbstractStringBuilder(int capacity) { value = new char[capacity]; } 当子类StringBuilder或StringBuffer实例化时,会在构造器中调用此构造器。 |
扩充容量 |
void expandCapacity(int minimumCapacity) |
此方法有包访问权限,类中有多个方法会调用此方法,在容量不足时扩充容量。 |
源码: void expandCapacity(int minimumCapacity) { int newCapacity = (value.length + 1) * 2; if (newCapacity < 0) { newCapacity = Integer.MAX_VALUE; } else if (minimumCapacity > newCapacity) { newCapacity = minimumCapacity; } value = Arrays.copyOf(value, newCapacity); } 将缓冲区长度加1乘2的值赋予变量newCapacity, 然后将此值与指定的值比较,将较大值确定为缓冲区的新容量;然后调用Arrays类的copyof方法,此方法会创建一个新数组,然后将原数组中的字符全部复制进新数组中。 |
ensureCapacity(int minimumCapacity) |
public void ensureCapacity(int minimumCapacity) |
确保容量至少等于指定的最小值。如果当前容量小于指定值,则创建新数组,新数组的容量为指定值的两倍加2;如果当前容量不小于指定值,则直接不做处理。 |
源码: public void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } |
测试: StringBuffer s = new StringBuffer(); System.out.println("容量:" + s.capacity());// 容量:16 s.ensureCapacity(10); System.out.println("容量:" + s.capacity());// 容量:16 s.ensureCapacity(30); System.out.println("容量:" + s.capacity());// 容量:34 s.ensureCapacity(80); System.out.println("容量:" + s.capacity());// 容量:80 |
length() |
public int length() |
返回缓冲区中的代码单元数。 |
注意:此方法返回的并不是字符的数量,因为对于Unicode增补字符1个代码点对应2个代码单元。可以通过codePointCount方法获取字符数。 |
源码: public int length() { return count; } |
Unicode标量值测试: StringBuffer s = new StringBuffer(); System.out.println(s.append(‘a‘).append(‘b‘).length());// 2 System.out.println(s.codePointCount(0, s.length()));// 2 Unicode增补字符测试: StringBuffer s = new StringBuffer(); System.out.println(s.append(‘\ud800‘).append(‘\udc00‘).length());// 2 System.out.println(s.codePointCount(0, s.length()));// 1 |
capacity() |
public int capacity() |
返回数组value的容量。 |
源码: public int capacity() { return value.length; } |
测试: System.out.println(s.capacity());// 10 System.out.println(s.length());// 0 |
反转 |
public AbstractStringBuilder reverse() |
将字符序列反转。 |
问题:我们知道对于Unicode 标量值只需要1个char变量即可表示,但对于增补字符却需要2个char变量,反转时如何正确的处理这些字符? 查看reverse源码: public AbstractStringBuilder reverse() { boolean hasSurrogate = false; int n = count - 1; for (int j = (n - 1) >> 1; j >= 0; --j) { char temp = value[j]; char temp2 = value[n - j]; if (!hasSurrogate) { hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE) || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE); } value[j] = temp2; value[n - j] = temp; } if (hasSurrogate) { // Reverse back all valid surrogate pairs for (int i = 0; i < count - 1; i++) { char c2 = value[i]; if (Character.isLowSurrogate(c2)) { char c1 = value[i + 1]; if (Character.isHighSurrogate(c1)) { value[i++] = c1; value[i] = c2; } } } } return this; } 可知此方法主要有两步: 1、用一个循环反转序列;并在每次循环时判断调换的两个字符是否有一个字符在\uD800和\uDFFF之间,如果有则置hasSurrogate的值为true。 2、若hasSurrogate的值为true,则进入第二个循环,调用Character类的isLowSurrogate和isHighSurrogate方法判断,将反转的增补字符再次反转,以此可确保字符的正确性。 |
添加 | |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
|
删除 |
public AbstractStringBuilder delete(int start, int end) |
删除字符序列中从start开始,end结束的子序列。 |
插入 | |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
| |||||
|
获取索引 | |||||
| |||||
| |||||
| |||||
|
替换 |
public AbstractStringBuilder replace(int start, int end, String str) |
用字符串str替换原字符序列中从start开始,end结束的子序列。 |
部分代码: if (end > count) end = count; int len = str.length(); int newCount = count + len - (end - start); if (newCount > value.length) expandCapacity(newCount); System.arraycopy(value, end, value, start + len, count - end); str.getChars(value, start); count = newCount; return this; |
获取子序列 | ||||
| ||||
| ||||
|
调整空间 |
public void trimToSize() |
试图减少字符序列的存储。如果缓冲区是大于必要的保持其当前的字符序列,然后可调整到更加节省空间。 |
源码: public void trimToSize() { if (count < value.length) { value = Arrays.copyOf(value, count); } }
|
测试: StringBuffer sb = new StringBuffer("12345"); System.out.println("字符串:" + sb + ";sb容量:" + sb.capacity());// 字符串:12345;缓冲区大小:21 sb.trimToSize(); System.out.println("字符串:" + sb + ";sb容量:" + sb.capacity());// 字符串:12345;缓冲区大小:5
|
设置长度 |
public void setLength(int newLength) |
指定字符序列新长度为newLength。 |
源码: public void setLength(int newLength) { if (newLength < 0) throw new StringIndexOutOfBoundsException(newLength); if (newLength > value.length) expandCapacity(newLength); if (count < newLength) { for (; count < newLength; count++) value[count] = ‘\0‘; } else { count = newLength; } }
|
测试: StringBuffer s = new StringBuffer("123456"); System.out.println("字符串:" + s + ";长度:" + s.length());// 字符串:123456;长度:6 s.setLength(3); System.out.println("字符串:" + s + ";长度:" + s.length());// 字符串:123;长度:3 s.setLength(9); System.out.println("字符串:" + s + ";长度:" + s.length());// 字符串:123 ;长度:9
|
获取字符 |
public char charAt(int index) |
返回指定索引处的代码单元。 |
注意:此方法返回的并不一定是字符,因为对于Unicode增补字符1个代码点对应2个代码单元。 |
源码: public char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; }
|
修改字符 |
public void setCharAt(int index, char ch) |
修改指定索引处(index)的代码单元为指定的代码单元(ch)。 |
源码: public void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); value[index] = ch; }
|
删除字符 |
public AbstractStringBuilder deleteCharAt(int index) |
删除字符序列中指定索引处的代码单元。 |
源码: public AbstractStringBuilder deleteCharAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); System.arraycopy(value, index + 1, value, index, count - index - 1); count--; return this; }
|
getChars |
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) |
源数组value从srcBegin开始,srcEnd结束的字符序列依次覆盖目的数组dst中从dstBegin开始的连续(srcEnd - srcBegin)个代码单元。 |
注意:覆盖的字符序列不能越界。 |
源码: public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) { if (srcBegin < 0) throw new StringIndexOutOfBoundsException(srcBegin); if ((srcEnd < 0) || (srcEnd > count)) throw new StringIndexOutOfBoundsException(srcEnd); if (srcBegin > srcEnd) throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); }
|
测试1: StringBuffer s = new StringBuffer("123"); char dst[] = { ‘a‘, ‘b‘, ‘c‘, ‘d‘ }; s.getChars(1, 2, dst, 2); System.out.println(dst);// ab2d 测试2: StringBuffer s = new StringBuffer("123"); char dst[] = { ‘a‘, ‘b‘, ‘c‘, ‘d‘ }; s.getChars(1, 4, dst, 2); System.out.println(dst); 打印: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 4
|
codePointAt(int index) |
public int codePointAt(int index) |
返回指定索引处的字符(Unicode code point)。 |
源码: public int codePointAt(int index) { if ((index < 0) || (index >= count)) { throw new StringIndexOutOfBoundsException(index); } return Character.codePointAt(value, index); }
|
标量值测试: StringBuffer s = new StringBuffer(); s.append(‘1‘).append(‘2‘); for (int i = 0; i < s.length(); i++) { System.out.println(s.codePointAt(i)); } 打印: 4950 增补字符测试: StringBuffer s = new StringBuffer(); s.append(‘\ud800‘).append(‘\udc00‘); for (int i = 0; i < s.length(); i++) { System.out.println(s.codePointAt(i)); } 打印: 6553656320 从测试中可以看出当字符序列中都是标量值字符时,直接输出对应的码点;当有增补字符时,那么,当索引指向的是高代理项时,就会输出整个增补字符的码点,当索引指向的是低代理项时,就会返回对应代码单元的码点。 |
codePointBefore(int index) |
public int codePointBefore(int index) |
返回指定索引前的字符(Unicode code point)。 |
部分源码: return Character.codePointBefore(value, index); |
标量值测试: StringBuffer s = new StringBuffer(); s.append(‘1‘).append(‘2‘).append(‘3‘); for (int i = 0; i < s.length(); i++) { if (i == 0) continue; System.out.println(s.codePointBefore(i)); } 打印: 4950 增补字符测试: StringBuffer s = new StringBuffer(); s.append(‘\ud800‘).append(‘\udc00‘).append(‘1‘); for (int i = 0; i < s.length(); i++) { if (i == 0) continue; System.out.println(s.codePointBefore(i)); } 打印: 5529665536 从测试中可以看出当字符序列中都是标量值字符时,输出指定索引处的码点;当有增补字符时,那么,当索引指向的是高代理项时,就会输出对应代码单元的码点;当索引指向的是低代理项时,就会返回整个增补字符的码点。 |
codePointCount(int beginIndex, int endIndex) |
public int codePointCount(int beginIndex, int endIndex) |
返回在指定的文本范围的Unicode代码点的数量。 |
源码: public int codePointCount(int beginIndex, int endIndex) { if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) { throw new IndexOutOfBoundsException(); } return Character.codePointCountImpl(value, beginIndex, endIndex - beginIndex); } 测试1: StringBuffer s = new StringBuffer("123123"); System.out.println(s.codePointCount(0, s.length()));// 6 测试2: StringBuffer s = new StringBuffer(); s.append(‘\ud800‘).append(‘\udc00‘); System.out.println(s.codePointCount(0, s.length()));// 1 从测试中可知对于Unicode标量值1个代码点对应1个char,对于Unicode增补字符1个代码点对应2个char。 |
offsetByCodePoints(int index, int codePointOffset) |
public int offsetByCodePoints(int index, int codePointOffset) |
offsetByCodePoints方法返回此String中从给定的index处偏移codePointOffset个代码点的索引。文本范围内由index和codePointOffset给定的未配对代理项各计为一个代码点。 |
源码: public int offsetByCodePoints(int index, int codePointOffset) { if (index < 0 || index > count) { throw new IndexOutOfBoundsException(); } return Character.offsetByCodePointsImpl(value, 0, count, index, codePointOffset); } |
测试: StringBuffer s = new StringBuffer(); s.append(‘1‘).append(‘2‘).append(‘\ud800‘).append(‘\udc00‘).append(‘1‘); System.out.println(s.offsetByCodePoints(0, 1)); System.out.println(s.offsetByCodePoints(0, 2)); System.out.println(s.offsetByCodePoints(0, 3)); 打印: 124
|
appendCodePoint(int codePoint) |
public AbstractStringBuilder appendCodePoint(int codePoint) |
添加指定代码点对应的字符。 |
源码: public AbstractStringBuilder appendCodePoint(int codePoint) { if (!Character.isValidCodePoint(codePoint)) { throw new IllegalArgumentException(); } int n = 1; if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { n++; } int newCount = count + n; if (newCount > value.length) { expandCapacity(newCount); } if (n == 1) { value[count++] = (char) codePoint; } else { Character.toSurrogates(codePoint, value, count); count += n; } return this; }
|
标量值测试: StringBuffer s = new StringBuffer(); s.appendCodePoint(49); System.out.println(s); System.out.println(s.length()); 打印: 11 增补字符测试: StringBuffer s = new StringBuffer(); s.appendCodePoint(65536); System.out.println(s); System.out.println(s.length()); 打印:
|
java之AbstractStringBuilder类详解