Java 源码分析(五)
来源:互联网 发布:ccw组态软件 编辑:程序博客网 时间:2024/06/14 06:48
在看StringBuilder和StringBuffer前,我们需要看一下AbstractStringBuilder类,因为前面两个类都继承于此。
1)value成员和count成员
char[] value;int count;
value用来储存字符串,count用来储存value的长度,这里有人会疑问,难道value.length不就是长度吗?在这里用value.length表示最大长度也即容量,而用count表示其实际长度。
2)构造方法
AbstractStringBuilder() {}AbstractStringBuilder(int capacity) {value = new char[capacity];}
第二个构造方法中传入的capacity,表示的就是容量。
3)length()和capacity()方法
public int length() {return count;}public int capacity() {return value.length;}
前者返回长度,后者返回容量。
4)ensureCapacity()方法
public void ensureCapacity(int minimumCapacity) {//参数合法扩容,不合法操作无效if (minimumCapacity > 0)ensureCapacityInternal(minimumCapacity);}private void ensureCapacityInternal(int minimumCapacity) {//参数合法扩容,不合法操作无效if (minimumCapacity - value.length > 0)expandCapacity(minimumCapacity);}void expandCapacity(int minimumCapacity) {//先扩充至原来长度乘2加2int newCapacity = value.length * 2 + 2;//如果小于参数,则直接扩容至参数大小if (newCapacity - minimumCapacity < 0)newCapacity = minimumCapacity;//溢出if (newCapacity < 0) {if (minimumCapacity < 0)throw new OutOfMemoryError();newCapacity = Integer.MAX_VALUE;}//复制之前数据value = Arrays.copyOf(value, newCapacity);}
5)trimToSize()方法
//将字符串的容量缩小至长度public void trimToSize() {if (count < value.length) {value = Arrays.copyOf(value, count);}}
6)setLength()方法
//扩充长度public void setLength(int newLength) {//检验参数合法性if (newLength < 0)throw new StringIndexOutOfBoundsException(newLength);//先扩容ensureCapacityInternal(newLength);//当前长度小于目标长度,用'\0'填充剩余部分(与扩容不同之处)if (count < newLength) {for (; count < newLength; count++)value[count] = '\0';} else {count = newLength;}}
7)charAt()方法
//取得某一位置的字符public char charAt(int index) {if ((index < 0) || (index >= count))throw new StringIndexOutOfBoundsException(index);return value[index];}
8)setCharAt()方法
//设置某一位置的字符public void setCharAt(int index, char ch) {if ((index < 0) || (index >= count))throw new StringIndexOutOfBoundsException(index);value[index] = ch;}
9)getChars()方法
//将value从srcBegin到srcEnd的字符串复制到dst的dstBegin处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");//将value从srcBegin起的(srcEnd-srcBegin)个字符复制到dst的dstBegin位置处System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);}
10)append()方法
public AbstractStringBuilder append(Object obj) {
returnappend(String.valueOf(obj));
}
public AbstractStringBuilder append(String str) {
//空字符串追加null四个字符
if (str == null) str ="null";
int len = str.length();
//扩容len长度
ensureCapacityInternal(count+ len);
//将要追加内容复制过去
str.getChars(0, len, value,count);
//更新长度
count += len;
return this;
}
public AbstractStringBuilder append(StringBuffer sb) {
if (sb == null)
returnappend("null");
int len = sb.length();
ensureCapacityInternal(count+ len);
sb.getChars(0, len, value,count);
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)
ensureCapacityInternal(count+ len);
//如果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) {
newFloatingDecimal(f).appendTo(this);
return this;
}
public AbstractStringBuilder append(double d) {
newFloatingDecimal(d).appendTo(this);
return this;
}
11)delete()方法
public AbstractStringBuilder delete(int start, int end) {//一连串参数合法性检测if (start < 0)throw new StringIndexOutOfBoundsException(start);if (end > count)end = count;if (start > end)throw new StringIndexOutOfBoundsException();int len = end - start;if (len > 0) {//利用复制自身实现删除System.arraycopy(value, start+len, value, start, count-end);count -= len;}return this;}
12)deleteCharAt()方法
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;}
13)replace()方法
public AbstractStringBuilder replace(int start, int end, String str) {if (start < 0)throw new StringIndexOutOfBoundsException(start);if (start > count)throw new StringIndexOutOfBoundsException("start > length()");if (start > end)throw new StringIndexOutOfBoundsException("start > end");if (end > count)end = count;int len = str.length();//计算新长度int newCount = count + len - (end - start);//扩容ensureCapacityInternal(newCount);//复制,实际上是删除start到end间的字符串System.arraycopy(value, end, value, start + len, count - end);//复制str.getChars(value, start);//更新长度count = newCount;return this;}
14)substring()方法
public String substring(int start) {return substring(start, count);}public String substring(int start, int end) {if (start < 0)throw new StringIndexOutOfBoundsException(start);if (end > count)throw new StringIndexOutOfBoundsException(end);if (start > end)throw new StringIndexOutOfBoundsException(end - start);return new String(value, start, end - start);}
15)insert()方法
public AbstractStringBuilder insert(int index, char[] str, int offset,int len) {if ((index < 0) || (index > length()))throw new StringIndexOutOfBoundsException(index);if ((offset < 0) || (len < 0) || (offset > str.length - len))throw new StringIndexOutOfBoundsException("offset " + offset + ", len " + len + ", str.length "+ str.length);//扩容ensureCapacityInternal(count + len);//利用复制增加长度,腾出str的空间System.arraycopy(value, index, value, index + len, count - index);//把str填进去System.arraycopy(str, offset, value, index, len);count += len;return this;}public AbstractStringBuilder insert(int offset, Object obj) {return insert(offset, String.valueOf(obj));}public AbstractStringBuilder insert(int offset, String str) {if ((offset < 0) || (offset > length()))throw new StringIndexOutOfBoundsException(offset);if (str == null)str = "null";int len = str.length();ensureCapacityInternal(count + len);System.arraycopy(value, offset, value, offset + len, count - offset);str.getChars(value, offset);count += len;return this;}public AbstractStringBuilder insert(int offset, char[] str) {if ((offset < 0) || (offset > length()))throw new StringIndexOutOfBoundsException(offset);int len = str.length;ensureCapacityInternal(count + len);System.arraycopy(value, offset, value, offset + len, count - offset);System.arraycopy(str, 0, value, offset, len);count += len;return this;}public AbstractStringBuilder insert(int dstOffset, CharSequence s) {if (s == null)s = "null";if (s instanceof String)return this.insert(dstOffset, (String)s);return this.insert(dstOffset, s, 0, s.length());} public AbstractStringBuilder insert(int dstOffset, CharSequence s, int start, int end) {if (s == null)s = "null";if ((dstOffset < 0) || (dstOffset > this.length()))throw new IndexOutOfBoundsException("dstOffset "+dstOffset);if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))throw new IndexOutOfBoundsException("start " + start + ", end " + end + ", s.length() "+ s.length());int len = end - start;ensureCapacityInternal(count + len);System.arraycopy(value, dstOffset, value, dstOffset + len, count - dstOffset);for (int i=start; i<end; i++)value[dstOffset++] = s.charAt(i);count += len;return this;}public AbstractStringBuilder insert(int offset, boolean b) {return insert(offset, String.valueOf(b));}public AbstractStringBuilder insert(int offset, char c) {ensureCapacityInternal(count + 1);System.arraycopy(value, offset, value, offset + 1, count - offset);value[offset] = c;count += 1;return this;}public AbstractStringBuilder insert(int offset, int i) {return insert(offset, String.valueOf(i));}public AbstractStringBuilder insert(int offset, long l) {return insert(offset, String.valueOf(l));}public AbstractStringBuilder insert(int offset, float f) {return insert(offset, String.valueOf(f));}public AbstractStringBuilder insert(int offset, double d) {return insert(offset, String.valueOf(d));}
16)reverse()方法
//颠倒字符串public AbstractStringBuilder reverse() {boolean hasSurrogate = false;int n = count - 1;//int j = (n-1)/2, n = count-1, j = count/2 - 1for (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) {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;}
接下来看StringBuilder和StringBuffer类。
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ public StringBuilder() { super(16); } public StringBuilder(int capacity) { super(capacity); } public StringBuilder(String str) { super(str.length() + 16); append(str); } public StringBuilder(CharSequence seq) { this(seq.length() + 16); append(seq); } public StringBuilder append(Object obj) { return append(String.valueOf(obj)); } public StringBuilder append(String str) { super.append(str); return this; } private StringBuilder append(StringBuilder sb) { if (sb == null) return append("null"); int len = sb.length(); int newcount = count + len; if (newcount > value.length) expandCapacity(newcount); sb.getChars(0, len, value, count); count = newcount; return this; } public StringBuilder append(StringBuffer sb) { super.append(sb); return this; } public StringBuilder append(CharSequence s) { if (s == null) s = "null"; if (s instanceof String) return this.append((String)s); if (s instanceof StringBuffer) return this.append((StringBuffer)s); if (s instanceof StringBuilder) return this.append((StringBuilder)s); return this.append(s, 0, s.length()); } public StringBuilder append(CharSequence s, int start, int end) { super.append(s, start, end); return this; } public StringBuilder append(char[] str) { super.append(str); return this; } public StringBuilder append(char[] str, int offset, int len) { super.append(str, offset, len); return this; } public StringBuilder append(boolean b) { super.append(b); return this; } public StringBuilder append(char c) { super.append(c); return this; } public StringBuilder append(int i) { super.append(i); return this; } public StringBuilder append(long lng) { super.append(lng); return this; } public StringBuilder append(float f) { super.append(f); return this; } public StringBuilder append(double d) { super.append(d); return this; } public StringBuilder appendCodePoint(int codePoint) { super.appendCodePoint(codePoint); return this; } public StringBuilder delete(int start, int end) { super.delete(start, end); return this; } public StringBuilder deleteCharAt(int index) { super.deleteCharAt(index); return this; } public StringBuilder replace(int start, int end, String str) { super.replace(start, end, str); return this; } public StringBuilder insert(int index, char[] str, int offset, int len) { super.insert(index, str, offset, len); return this; } public StringBuilder insert(int offset, Object obj) { return insert(offset, String.valueOf(obj)); } public StringBuilder insert(int offset, String str) { super.insert(offset, str); return this; } public StringBuilder insert(int offset, char[] str) { super.insert(offset, str); return this; } public StringBuilder insert(int dstOffset, CharSequence s) { if (s == null) s = "null"; if (s instanceof String) return this.insert(dstOffset, (String)s); return this.insert(dstOffset, s, 0, s.length()); } public StringBuilder insert(int dstOffset, CharSequence s, int start, int end) { super.insert(dstOffset, s, start, end); return this; } public StringBuilder insert(int offset, boolean b) { super.insert(offset, b); return this; } public StringBuilder insert(int offset, char c) { super.insert(offset, c); return this; } public StringBuilder insert(int offset, int i) { return insert(offset, String.valueOf(i)); } public StringBuilder insert(int offset, long l) { return insert(offset, String.valueOf(l)); } public StringBuilder insert(int offset, float f) { return insert(offset, String.valueOf(f)); } public StringBuilder insert(int offset, double d) { return insert(offset, String.valueOf(d)); } public int indexOf(String str) { return indexOf(str, 0); } public int indexOf(String str, int fromIndex) { return String.indexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } public int lastIndexOf(String str) { return lastIndexOf(str, count); } public int lastIndexOf(String str, int fromIndex) { return String.lastIndexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } public StringBuilder reverse() { super.reverse(); return this; } public String toString() { return new String(value, 0, count); } private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { s.defaultWriteObject(); s.writeInt(count); s.writeObject(value); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); count = s.readInt(); value = (char[]) s.readObject(); }}
可以看出StringBuilder大部分方法是使用的父类AbstractStringBuilder的方法,再看StringBuffer类。
package java.lang; public final class StringBuffer extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ public StringBuffer() { super(16); } public StringBuffer(int capacity) { super(capacity); } public StringBuffer(String str) { super(str.length() + 16); append(str); } public StringBuffer(CharSequence seq) { this(seq.length() + 16); append(seq); } public synchronized int length() { return count; } public synchronized int capacity() { return value.length; } public synchronized void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); } } public synchronized void trimToSize() { super.trimToSize(); } public synchronized void setLength(int newLength) { super.setLength(newLength); } public synchronized char charAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); return value[index]; } public synchronized int codePointAt(int index) { return super.codePointAt(index); } public synchronized int codePointBefore(int index) { return super.codePointBefore(index); } public synchronized int codePointCount(int beginIndex, int endIndex) { return super.codePointCount(beginIndex, endIndex); } public synchronized int offsetByCodePoints(int index, int codePointOffset) { return super.offsetByCodePoints(index, codePointOffset); } public synchronized void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin) { super.getChars(srcBegin, srcEnd, dst, dstBegin); } public synchronized void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); value[index] = ch; } public synchronized StringBuffer append(Object obj) { super.append(String.valueOf(obj)); return this; } public synchronized StringBuffer append(String str) { super.append(str); return this; } public synchronized StringBuffer append(StringBuffer sb) { super.append(sb); return this; } public StringBuffer append(CharSequence s) { if (s == null) s = "null"; if (s instanceof String) return this.append((String)s); if (s instanceof StringBuffer) return this.append((StringBuffer)s); return this.append(s, 0, s.length()); } public synchronized StringBuffer append(CharSequence s, int start, int end) { super.append(s, start, end); return this; } public synchronized StringBuffer append(char[] str) { super.append(str); return this; } public synchronized StringBuffer append(char[] str, int offset, int len) { super.append(str, offset, len); return this; } public synchronized StringBuffer append(boolean b) { super.append(b); return this; } public synchronized StringBuffer append(char c) { super.append(c); return this; } public synchronized StringBuffer append(int i) { super.append(i); return this; } public synchronized StringBuffer appendCodePoint(int codePoint) { super.appendCodePoint(codePoint); return this; } public synchronized StringBuffer append(long lng) { super.append(lng); return this; } public synchronized StringBuffer append(float f) { super.append(f); return this; } public synchronized StringBuffer append(double d) { super.append(d); return this; } public synchronized StringBuffer delete(int start, int end) { super.delete(start, end); return this; } public synchronized StringBuffer deleteCharAt(int index) { super.deleteCharAt(index); return this; } public synchronized StringBuffer replace(int start, int end, String str) { 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) { super.insert(index, str, offset, len); return this; } public synchronized StringBuffer insert(int offset, Object obj) { super.insert(offset, String.valueOf(obj)); return this; } public synchronized StringBuffer insert(int offset, String str) { super.insert(offset, str); return this; } public synchronized StringBuffer insert(int offset, char[] str) { super.insert(offset, str); return this; } public StringBuffer insert(int dstOffset, CharSequence s) { if (s == null) s = "null"; if (s instanceof String) return this.insert(dstOffset, (String)s); return this.insert(dstOffset, s, 0, s.length()); } public synchronized StringBuffer insert(int dstOffset, CharSequence s, int start, int end) { super.insert(dstOffset, s, start, end); return this; } public StringBuffer insert(int offset, boolean b) { return insert(offset, String.valueOf(b)); } public synchronized StringBuffer insert(int offset, char c) { super.insert(offset, c); return this; } public StringBuffer insert(int offset, int i) { return insert(offset, String.valueOf(i)); } public StringBuffer insert(int offset, long l) { return insert(offset, String.valueOf(l)); } public StringBuffer insert(int offset, float f) { return insert(offset, String.valueOf(f)); } public StringBuffer insert(int offset, double d) { return insert(offset, String.valueOf(d)); } public int indexOf(String str) { return indexOf(str, 0); } public synchronized int indexOf(String str, int fromIndex) { return String.indexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } public int lastIndexOf(String str) { return lastIndexOf(str, count); } public synchronized int lastIndexOf(String str, int fromIndex) { return String.lastIndexOf(value, 0, count, str.toCharArray(), 0, str.length(), fromIndex); } public synchronized StringBuffer reverse() { super.reverse(); return this; } public synchronized String toString() { return new String(value, 0, count); } private static final java.io.ObjectStreamField[] serialPersistentFields = { new java.io.ObjectStreamField("value", char[].class), new java.io.ObjectStreamField("count", Integer.TYPE), new java.io.ObjectStreamField("shared", Boolean.TYPE), }; private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { java.io.ObjectOutputStream.PutField fields = s.putFields(); fields.put("value", value); fields.put("count", count); fields.put("shared", false); s.writeFields(); } private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { java.io.ObjectInputStream.GetField fields = s.readFields(); value = (char[])fields.get("value", null); count = fields.get("count", 0); }}
同样也是多用父类的方法,但是大部分方法都用关键词synchronized修饰,所以说StringBuffer是线程安全的,但是效率有所下降。
- Java 源码分析(五)
- java 中的集合(五) LinkedList源码分析
- JAVA 并发类(五) CopyOnWriteArraySet 源码分析
- Java多线程系列(五)—LockSupport源码分析
- quake3源码分析(五)
- Logcat源码分析(五)
- pomelo源码分析(五)
- mosquitto源码分析(五)
- openMPM源码分析(五)
- mosquitto源码分析(五)
- mosquitto源码分析(五)
- DispatcherServlet 源码分析(五)
- orbslam 源码分析(五)
- YOLOv2源码分析(五)
- Netty源码分析(五)—ByteBuf源码分析
- uC/OS-II源码分析(五)
- Spring源码分析-初识ProxyFactoryBean(五)
- Spark的standalone源码分析(五)
- html5标签用css限制显示行数(字数)
- 66、java集合-Map
- 解决You have an error in your SQL syntax; check the manual that corresponds to your MySQL server错误
- 高手教你零基础系统地学习前端开发
- matlab生成多个文件夹,并根据文件的文件名粘贴进文件夹的小脚本
- Java 源码分析(五)
- dfs学习之寻找朋友圈数
- js获取useragent以此更改链接
- 67、java集合-HashMap
- ora-600 [keltnfy-ldmlnit] 错误处理一DBCA建库时报错
- The C Programming Language 练习题4-1
- linux把文件压缩成.tar.gz的命令
- Linux Workqueue
- struts2如何封装具有相同名称的一组值:注意“,空格”