String
类是java.lang
包下的类,也是Java程序员最熟悉的类,它代表着字符串。同时String
被final
关键字修饰,说明它是不可被继承的类,内部的所有成员方法都是final
方法。String
内部是使用一个char数组来维持着一个字符串。
String
对象不能被更改,也就是说字符串是不可以被改变的。那如果想要改变一个字符串就要用到StringBuilder
类,其中append()
方法是将传入参数的值追加到字符序列的尾部。
StringBuffer
和StringBuilder
的功能是一样的,可以把StringBuffer
看成线程安全的StringBuilder
。
继承结构
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence
//不带字符串的缓冲区,初始容量为16
public StringBuffer() {
//默认容量
super(16);
}
//不带字符串的缓冲区,指定初始容量
public StringBuffer(int capacity) {
super(capacity);
}
//带字符串的缓冲区,缓冲区大小是字符串长度+16
public StringBuffer(String str) {
super(str.length() + 16);
append(str);
}
//包含和CharSequence相同字符的缓冲区,缓冲区大小是seq的长度+16
public StringBuffer(CharSequence seq) {
this(seq.length() + 16);
append(seq);
}
/**
* 字符串的缓存,如果append就clear
*/
private transient char[] toStringCache;
继承于AbstractStringBuilder
的属性
/**
* 存储数据的数组,默认大小16
*/
char[] value;
/**
* 字符串实际长度
*/
int count;
append
算是StringBuffer
最常用的方法了,调用的都是超类中的append
方法。所以直接看AbstractStringBuilder
的方法。
public AbstractStringBuilder append(Object obj) {
//实际就是调用Object的toString方法
return append(String.valueOf(obj));
}
public AbstractStringBuilder append(String str) {
//字符串为空,就调用appendNull方法,添加"null"
if (str == null)
return appendNull();
int len = str.length();
//重新设置value数组的长度
ensureCapacityInternal(count + len);
//copy str的内容
str.getChars(0, len, value, count);
count += len;
return this;
}
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
return appendNull();
int len = sb.length();
ensureCapacityInternal(count + len);
sb.getChars(0, len, value, count);
count += len;
return this;
}
AbstractStringBuilder append(AbstractStringBuilder asb) {
if (asb == null)
return appendNull();
int len = asb.length();
ensureCapacityInternal(count + len);
asb.getChars(0, len, value, count);
count += len;
return this;
}
@Override
public AbstractStringBuilder append(CharSequence s) {
if (s == null)
return appendNull();
if (s instanceof String)
return this.append((String)s);
if (s instanceof AbstractStringBuilder)
return this.append((AbstractStringBuilder)s);
return this.append(s, 0, s.length());
}
//添加null
private AbstractStringBuilder appendNull() {
int c = count;
ensureCapacityInternal(c + 4);
final char[] value = this.value;
value[c++] = 'n';
value[c++] = 'u';
value[c++] = 'l';
value[c++] = 'l';
count = c;
return this;
}
public AbstractStringBuilder append(CharSequence s, int start, int end) {
if (s == null)
s = "null";
if ((start < 0) || (start > end) || (end > s.length()))
throw new IndexOutOfBoundsException(
"start " + start + ", end " + end + ", s.length() "
+ s.length());
int len = end - start;
ensureCapacityInternal(count + len);
for (int i = start, j = count; i < end; i++, j++)
value[j] = s.charAt(i);
count += len;
return this;
}
public AbstractStringBuilder append(char[] str) {
int len = str.length;
ensureCapacityInternal(count + len);
System.arraycopy(str, 0, value, count, len);
count += len;
return this;
}
public AbstractStringBuilder append(char str[], int offset, int len) {
if (len > 0) // let arraycopy report AIOOBE for len < 0
ensureCapacityInternal(count + len);
System.arraycopy(str, offset, value, count, len);
count += len;
return this;
}
public AbstractStringBuilder append(boolean b) {
if (b) {
ensureCapacityInternal(count + 4);
value[count++] = 't';
value[count++] = 'r';
value[count++] = 'u';
value[count++] = 'e';
} else {
ensureCapacityInternal(count + 5);
value[count++] = 'f';
value[count++] = 'a';
value[count++] = 'l';
value[count++] = 's';
value[count++] = 'e';
}
return this;
}
public AbstractStringBuilder append(char c) {
ensureCapacityInternal(count + 1);
value[count++] = c;
return this;
}
public AbstractStringBuilder append(int i) {
if (i == Integer.MIN_VALUE) {
append("-2147483648");
return this;
}
int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
: Integer.stringSize(i);
int spaceNeeded = count + appendedLength;
ensureCapacityInternal(spaceNeeded);
Integer.getChars(i, spaceNeeded, value);
count = spaceNeeded;
return this;
}
public AbstractStringBuilder append(long l) {
if (l == Long.MIN_VALUE) {
append("-9223372036854775808");
return this;
}
int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
: Long.stringSize(l);
int spaceNeeded = count + appendedLength;
ensureCapacityInternal(spaceNeeded);
Long.getChars(l, spaceNeeded, value);
count = spaceNeeded;
return this;
}
public AbstractStringBuilder append(float f) {
FloatingDecimal.appendTo(f,this);
return this;
}
public AbstractStringBuilder append(double d) {
FloatingDecimal.appendTo(d,this);
return this;
}
//返回value实际使用的长度
public synchronized int length() {
return count;
}
//返回value数组的容量
public synchronized int capacity() {
return value.length;
}
//扩容成大小为minimumCapacity的大小
public synchronized void ensureCapacity(int minimumCapacity) {
super.ensureCapacity(minimumCapacity);
}
//去除value中用作cache的部分
public synchronized void trimToSize() {
super.trimToSize();
}
//设置新的长度
public synchronized void setLength(int newLength) {
toStringCache = null;
super.setLength(newLength);
}
public char charAt(int index) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
return value[index];
}
public int indexOf(String str) {
return indexOf(str, 0);
}
//调用的是String的indexof方法
public int indexOf(String str, int fromIndex) {
return String.indexOf(value, 0, count, str, fromIndex);
}
//char替换
public synchronized void setCharAt(int index, char ch) {
if ((index < 0) || (index >= count))
throw new StringIndexOutOfBoundsException(index);
toStringCache = null;
value[index] = ch;
}
//String替换
public synchronized StringBuffer replace(int start, int end, String str) {
toStringCache = null;
super.replace(start, end, str);
return this;
}
public synchronized String substring(int start) {
return substring(start, count);
}
public synchronized CharSequence subSequence(int start, int end) {
return super.substring(start, end);
}
public synchronized String substring(int start, int end) {
return super.substring(start, end);
}
public synchronized StringBuffer insert(int index, char[] str, int offset,
int len)
{
toStringCache = null;
super.insert(index, str, offset, len);
return this;
}
public synchronized StringBuffer insert(int offset, Object obj) {
toStringCache = null;
super.insert(offset, String.valueOf(obj));
return this;
}
public synchronized StringBuffer insert(int offset, String str) {
toStringCache = null;
super.insert(offset, str);
return this;
}
public synchronized StringBuffer insert(int offset, char[] str) {
toStringCache = null;
super.insert(offset, str);
return this;
}
public StringBuffer insert(int dstOffset, CharSequence s) {
super.insert(dstOffset, s);
return this;
}
public synchronized StringBuffer insert(int dstOffset, CharSequence s,
int start, int end){
toStringCache = null;
super.insert(dstOffset, s, start, end);
return this;
}
public StringBuffer insert(int offset, boolean b) {
super.insert(offset, b);
return this;
}
public synchronized StringBuffer insert(int offset, char c) {
toStringCache = null;
super.insert(offset, c);
return this;
}
public StringBuffer insert(int offset, int i) {
super.insert(offset, i);
return this;
}
public StringBuffer insert(int offset, long l) {
super.insert(offset, l);
return this;
}
public StringBuffer insert(int offset, float f) {
super.insert(offset, f);
return this;
}
public StringBuffer insert(int offset, double d) {
super.insert(offset, d);
return this;
}
public synchronized StringBuffer reverse() {
toStringCache = null;
super.reverse();
return this;
}
//超类中reverse方法
public AbstractStringBuilder reverse() {
boolean hasSurrogates = false;
int n = count - 1;
for (int j = (n-1) >> 1; j >= 0; j--) {
int k = n - j;
char cj = value[j];
char ck = value[k];
value[j] = ck;
value[k] = cj;
//确定给定的 char值是否是Unicode 代理代码单元 。
if (Character.isSurrogate(cj) ||
Character.isSurrogate(ck)) {
hasSurrogates = true;
}
}
if (hasSurrogates) {
reverseAllValidSurrogatePairs();
}
return this;
}
private void reverseAllValidSurrogatePairs() {
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;
}
}
}
}
public synchronized String toString() {
//更新toStringCache
if (toStringCache == null) {
toStringCache = Arrays.copyOfRange(value, 0, count);
}
return new String(toStringCache, true);
}