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是线程安全的,但是效率有所下降。







原创粉丝点击