目录
从https://www.cnblogs.com/twzheng/p/5923642.html一文的结论进行验证。
发现效率StringBuilder和StringBuffer的结果是相反的,故此本文加以论证。
实验报告
StringBuffer>StringBuilder>StringJoin>StringContact>StringPlus+
测试代码
用其原文测试代码:
- public class StringUtilsTests {
-
- private static final int max = 1000000;
-
- @Test
- public void testPlus() {
- System.out.println(">>> testPlus() <<<");
-
- String str = "";
-
- long start = System.currentTimeMillis();
-
- for (int i = 0; i < max; i++) {
- str = str + "a";
- }
-
- long end = System.currentTimeMillis();
-
- long cost = end - start;
-
- System.out.println(" {str + \"a\"} cost=" + cost + " ms");
- }
-
- @Test
- public void testConcat() {
- System.out.println(">>> testConcat() <<<");
-
- String str = "";
-
- long start = System.currentTimeMillis();
-
- for (int i = 0; i < max; i++) {
- str = str.concat("a");
- }
-
- long end = System.currentTimeMillis();
-
- long cost = end - start;
-
- System.out.println(" {str.concat(\"a\")} cost=" + cost + " ms");
- }
-
- @Test
- public void testJoin() {
- System.out.println(">>> testJoin() <<<");
-
- long start = System.currentTimeMillis();
-
- List<String> list = new ArrayList<String>();
-
- for (int i = 0; i < max; i++) {
- list.add("a");
- }
-
- long end1 = System.currentTimeMillis();
- long cost1 = end1 - start;
-
- StringUtils.join(list, "");
-
- long end = System.currentTimeMillis();
- long cost = end - end1;
-
- System.out.println(" {list.add(\"a\")} cost1=" + cost1 + " ms");
- System.out.println(" {StringUtils.join(list, \"\")} cost=" + cost
- + " ms");
- }
-
- @Test
- public void testStringBuffer() {
- System.out.println(">>> testStringBuffer() <<<");
-
- long start = System.currentTimeMillis();
-
- StringBuffer strBuffer = new StringBuffer();
-
- for (int i = 0; i < max; i++) {
- strBuffer.append("a");
- }
- strBuffer.toString();
-
- long end = System.currentTimeMillis();
-
- long cost = end - start;
-
- System.out.println(" {strBuffer.append(\"a\")} cost=" + cost + " ms");
- }
-
- @Test
- public void testStringBuilder() {
- System.out.println(">>> testStringBuilder() <<<");
-
- long start = System.currentTimeMillis();
-
- StringBuilder strBuilder = new StringBuilder();
-
- for (int i = 0; i < max; i++) {
- strBuilder.append("a");
- }
- strBuilder.toString();
-
- long end = System.currentTimeMillis();
-
- long cost = end - start;
-
- System.out
- .println(" {strBuilder.append(\"a\")} cost=" + cost + " ms");
- }
-
-
-
- }
StringBuffer
我们重点看append的实现调用的是AbstractStringBuilder类方法:
- @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());
- }
-
最终调用的是String的字符数组拷贝机制:
- /**
- * Copies characters from this string into the destination character
- * array.
- * <p>
- * The first character to be copied is at index {@code srcBegin};
- * the last character to be copied is at index {@code srcEnd-1}
- * (thus the total number of characters to be copied is
- * {@code srcEnd-srcBegin}). The characters are copied into the
- * subarray of {@code dst} starting at index {@code dstBegin}
- * and ending at index:
- * <blockquote><pre>
- * dstBegin + (srcEnd-srcBegin) - 1
- * </pre></blockquote>
- *
- * @param srcBegin index of the first character in the string
- * to copy.
- * @param srcEnd index after the last character in the string
- * to copy.
- * @param dst the destination array.
- * @param dstBegin the start offset in the destination array.
- * @exception IndexOutOfBoundsException If any of the following
- * is true:
- * <ul><li>{@code srcBegin} is negative.
- * <li>{@code srcBegin} is greater than {@code srcEnd}
- * <li>{@code srcEnd} is greater than the length of this
- * string
- * <li>{@code dstBegin} is negative
- * <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
- * {@code dst.length}</ul>
- */
- public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
- if (srcBegin < 0) {
- throw new StringIndexOutOfBoundsException(srcBegin);
- }
- if (srcEnd > value.length) {
- throw new StringIndexOutOfBoundsException(srcEnd);
- }
- if (srcBegin > srcEnd) {
- throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
- }
- System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
- }
StringBuffer源码:
- public final class StringBuffer
- extends AbstractStringBuilder
- implements java.io.Serializable, CharSequence
- {
-
- /**
- * A cache of the last value returned by toString. Cleared
- * whenever the StringBuffer is modified.
- */
- private transient char[] toStringCache;
-
- /** use serialVersionUID from JDK 1.0.2 for interoperability */
- static final long serialVersionUID = 3388685877147921107L;
-
- /**
- * Constructs a string buffer with no characters in it and an
- * initial capacity of 16 characters.
- */
- public StringBuffer() {
- super(16);
- }
-
- /**
- * Constructs a string buffer with no characters in it and
- * the specified initial capacity.
- *
- * @param capacity the initial capacity.
- * @exception NegativeArraySizeException if the {@code capacity}
- * argument is less than {@code 0}.
- */
- public StringBuffer(int capacity) {
- super(capacity);
- }
-
- /**
- * Constructs a string buffer initialized to the contents of the
- * specified string. The initial capacity of the string buffer is
- * {@code 16} plus the length of the string argument.
- *
- * @param str the initial contents of the buffer.
- */
- public StringBuffer(String str) {
- super(str.length() + 16);
- append(str);
- }
-
- /**
- * Constructs a string buffer that contains the same characters
- * as the specified {@code CharSequence}. The initial capacity of
- * the string buffer is {@code 16} plus the length of the
- * {@code CharSequence} argument.
- * <p>
- * If the length of the specified {@code CharSequence} is
- * less than or equal to zero, then an empty buffer of capacity
- * {@code 16} is returned.
- *
- * @param seq the sequence to copy.
- * @since 1.5
- */
- public StringBuffer(CharSequence seq) {
- this(seq.length() + 16);
- append(seq);
- }
-
- @Override
- public synchronized int length() {
- return count;
- }
-
- @Override
- public synchronized int capacity() {
- return value.length;
- }
-
-
- @Override
- public synchronized void ensureCapacity(int minimumCapacity) {
- super.ensureCapacity(minimumCapacity);
- }
-
- /**
- * @since 1.5
- */
- @Override
- public synchronized void trimToSize() {
- super.trimToSize();
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @see #length()
- */
- @Override
- public synchronized void setLength(int newLength) {
- toStringCache = null;
- super.setLength(newLength);
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @see #length()
- */
- @Override
- public synchronized char charAt(int index) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
- return value[index];
- }
-
- /**
- * @since 1.5
- */
- @Override
- public synchronized int codePointAt(int index) {
- return super.codePointAt(index);
- }
-
- /**
- * @since 1.5
- */
- @Override
- public synchronized int codePointBefore(int index) {
- return super.codePointBefore(index);
- }
-
- /**
- * @since 1.5
- */
- @Override
- public synchronized int codePointCount(int beginIndex, int endIndex) {
- return super.codePointCount(beginIndex, endIndex);
- }
-
- /**
- * @since 1.5
- */
- @Override
- public synchronized int offsetByCodePoints(int index, int codePointOffset) {
- return super.offsetByCodePoints(index, codePointOffset);
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
- int dstBegin)
- {
- super.getChars(srcBegin, srcEnd, dst, dstBegin);
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @see #length()
- */
- @Override
- public synchronized void setCharAt(int index, char ch) {
- if ((index < 0) || (index >= count))
- throw new StringIndexOutOfBoundsException(index);
- toStringCache = null;
- value[index] = ch;
- }
-
- @Override
- public synchronized StringBuffer append(Object obj) {
- toStringCache = null;
- super.append(String.valueOf(obj));
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(String str) {
- toStringCache = null;
- super.append(str);
- return this;
- }
-
- /**
- * Appends the specified {@code StringBuffer} to this sequence.
- * <p>
- * The characters of the {@code StringBuffer} argument are appended,
- * in order, to the contents of this {@code StringBuffer}, increasing the
- * length of this {@code StringBuffer} by the length of the argument.
- * If {@code sb} is {@code null}, then the four characters
- * {@code "null"} are appended to this {@code StringBuffer}.
- * <p>
- * Let <i>n</i> be the length of the old character sequence, the one
- * contained in the {@code StringBuffer} just prior to execution of the
- * {@code append} method. Then the character at index <i>k</i> in
- * the new character sequence is equal to the character at index <i>k</i>
- * in the old character sequence, if <i>k</i> is less than <i>n</i>;
- * otherwise, it is equal to the character at index <i>k-n</i> in the
- * argument {@code sb}.
- * <p>
- * This method synchronizes on {@code this}, the destination
- * object, but does not synchronize on the source ({@code sb}).
- *
- * @param sb the {@code StringBuffer} to append.
- * @return a reference to this object.
- * @since 1.4
- */
- public synchronized StringBuffer append(StringBuffer sb) {
- toStringCache = null;
- super.append(sb);
- return this;
- }
-
- /**
- * @since 1.8
- */
- @Override
- synchronized StringBuffer append(AbstractStringBuilder asb) {
- toStringCache = null;
- super.append(asb);
- return this;
- }
-
- /**
- * Appends the specified {@code CharSequence} to this
- * sequence.
- * <p>
- * The characters of the {@code CharSequence} argument are appended,
- * in order, increasing the length of this sequence by the length of the
- * argument.
- *
- * <p>The result of this method is exactly the same as if it were an
- * invocation of this.append(s, 0, s.length());
- *
- * <p>This method synchronizes on {@code this}, the destination
- * object, but does not synchronize on the source ({@code s}).
- *
- * <p>If {@code s} is {@code null}, then the four characters
- * {@code "null"} are appended.
- *
- * @param s the {@code CharSequence} to append.
- * @return a reference to this object.
- * @since 1.5
- */
- @Override
- public synchronized StringBuffer append(CharSequence s) {
- toStringCache = null;
- super.append(s);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @since 1.5
- */
- @Override
- public synchronized StringBuffer append(CharSequence s, int start, int end)
- {
- toStringCache = null;
- super.append(s, start, end);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(char[] str) {
- toStringCache = null;
- super.append(str);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public synchronized StringBuffer append(char[] str, int offset, int len) {
- toStringCache = null;
- super.append(str, offset, len);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(boolean b) {
- toStringCache = null;
- super.append(b);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(char c) {
- toStringCache = null;
- super.append(c);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(int i) {
- toStringCache = null;
- super.append(i);
- return this;
- }
-
- /**
- * @since 1.5
- */
- @Override
- public synchronized StringBuffer appendCodePoint(int codePoint) {
- toStringCache = null;
- super.appendCodePoint(codePoint);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(long lng) {
- toStringCache = null;
- super.append(lng);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(float f) {
- toStringCache = null;
- super.append(f);
- return this;
- }
-
- @Override
- public synchronized StringBuffer append(double d) {
- toStringCache = null;
- super.append(d);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- * @since 1.2
- */
- @Override
- public synchronized StringBuffer delete(int start, int end) {
- toStringCache = null;
- super.delete(start, end);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- * @since 1.2
- */
- @Override
- public synchronized StringBuffer deleteCharAt(int index) {
- toStringCache = null;
- super.deleteCharAt(index);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- * @since 1.2
- */
- @Override
- public synchronized StringBuffer replace(int start, int end, String str) {
- toStringCache = null;
- super.replace(start, end, str);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- * @since 1.2
- */
- @Override
- public synchronized String substring(int start) {
- return substring(start, count);
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @since 1.4
- */
- @Override
- public synchronized CharSequence subSequence(int start, int end) {
- return super.substring(start, end);
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- * @since 1.2
- */
- @Override
- public synchronized String substring(int start, int end) {
- return super.substring(start, end);
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- * @since 1.2
- */
- @Override
- public synchronized StringBuffer insert(int index, char[] str, int offset,
- int len)
- {
- toStringCache = null;
- super.insert(index, str, offset, len);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public synchronized StringBuffer insert(int offset, Object obj) {
- toStringCache = null;
- super.insert(offset, String.valueOf(obj));
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public synchronized StringBuffer insert(int offset, String str) {
- toStringCache = null;
- super.insert(offset, str);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public synchronized StringBuffer insert(int offset, char[] str) {
- toStringCache = null;
- super.insert(offset, str);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @since 1.5
- */
- @Override
- public StringBuffer insert(int dstOffset, CharSequence s) {
- // Note, synchronization achieved via invocations of other StringBuffer methods
- // after narrowing of s to specific type
- // Ditto for toStringCache clearing
- super.insert(dstOffset, s);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- * @since 1.5
- */
- @Override
- public synchronized StringBuffer insert(int dstOffset, CharSequence s,
- int start, int end)
- {
- toStringCache = null;
- super.insert(dstOffset, s, start, end);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuffer insert(int offset, boolean b) {
- // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
- // after conversion of b to String by super class method
- // Ditto for toStringCache clearing
- super.insert(offset, b);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public synchronized StringBuffer insert(int offset, char c) {
- toStringCache = null;
- super.insert(offset, c);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuffer insert(int offset, int i) {
- // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
- // after conversion of i to String by super class method
- // Ditto for toStringCache clearing
- super.insert(offset, i);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuffer insert(int offset, long l) {
- // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
- // after conversion of l to String by super class method
- // Ditto for toStringCache clearing
- super.insert(offset, l);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuffer insert(int offset, float f) {
- // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
- // after conversion of f to String by super class method
- // Ditto for toStringCache clearing
- super.insert(offset, f);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuffer insert(int offset, double d) {
- // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
- // after conversion of d to String by super class method
- // Ditto for toStringCache clearing
- super.insert(offset, d);
- return this;
- }
-
- /**
- * @since 1.4
- */
- @Override
- public int indexOf(String str) {
- // Note, synchronization achieved via invocations of other StringBuffer methods
- return super.indexOf(str);
- }
-
- /**
- * @since 1.4
- */
- @Override
- public synchronized int indexOf(String str, int fromIndex) {
- return super.indexOf(str, fromIndex);
- }
-
- /**
- * @since 1.4
- */
- @Override
- public int lastIndexOf(String str) {
- // Note, synchronization achieved via invocations of other StringBuffer methods
- return lastIndexOf(str, count);
- }
-
- /**
- * @since 1.4
- */
- @Override
- public synchronized int lastIndexOf(String str, int fromIndex) {
- return super.lastIndexOf(str, fromIndex);
- }
-
- /**
- * @since JDK1.0.2
- */
- @Override
- public synchronized StringBuffer reverse() {
- toStringCache = null;
- super.reverse();
- return this;
- }
-
- @Override
- public synchronized String toString() {
- if (toStringCache == null) {
- toStringCache = Arrays.copyOfRange(value, 0, count);
- }
- return new String(toStringCache, true);
- }
-
- /**
- * Serializable fields for StringBuffer.
- *
- * @serialField value char[]
- * The backing character array of this StringBuffer.
- * @serialField count int
- * The number of characters in this StringBuffer.
- * @serialField shared boolean
- * A flag indicating whether the backing array is shared.
- * The value is ignored upon deserialization.
- */
- 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),
- };
-
- /**
- * readObject is called to restore the state of the StringBuffer from
- * a stream.
- */
- 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();
- }
-
- /**
- * readObject is called to restore the state of the StringBuffer from
- * a stream.
- */
- 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);
- }
- }
StringBuilder
StringBuilder的实现与StringBuffer代码上差不多,但StringBuffer是使用了锁是线程安全的。
- public final class StringBuilder
- extends AbstractStringBuilder
- implements java.io.Serializable, CharSequence
- {
-
- /** use serialVersionUID for interoperability */
- static final long serialVersionUID = 4383685877147921099L;
-
- /**
- * Constructs a string builder with no characters in it and an
- * initial capacity of 16 characters.
- */
- public StringBuilder() {
- super(16);
- }
-
- /**
- * Constructs a string builder with no characters in it and an
- * initial capacity specified by the {@code capacity} argument.
- *
- * @param capacity the initial capacity.
- * @throws NegativeArraySizeException if the {@code capacity}
- * argument is less than {@code 0}.
- */
- public StringBuilder(int capacity) {
- super(capacity);
- }
-
- /**
- * Constructs a string builder initialized to the contents of the
- * specified string. The initial capacity of the string builder is
- * {@code 16} plus the length of the string argument.
- *
- * @param str the initial contents of the buffer.
- */
- public StringBuilder(String str) {
- super(str.length() + 16);
- append(str);
- }
-
- /**
- * Constructs a string builder that contains the same characters
- * as the specified {@code CharSequence}. The initial capacity of
- * the string builder is {@code 16} plus the length of the
- * {@code CharSequence} argument.
- *
- * @param seq the sequence to copy.
- */
- public StringBuilder(CharSequence seq) {
- this(seq.length() + 16);
- append(seq);
- }
-
- @Override
- public StringBuilder append(Object obj) {
- return append(String.valueOf(obj));
- }
-
- @Override
- public StringBuilder append(String str) {
- super.append(str);
- return this;
- }
-
- /**
- * Appends the specified {@code StringBuffer} to this sequence.
- * <p>
- * The characters of the {@code StringBuffer} argument are appended,
- * in order, to this sequence, increasing the
- * length of this sequence by the length of the argument.
- * If {@code sb} is {@code null}, then the four characters
- * {@code "null"} are appended to this sequence.
- * <p>
- * Let <i>n</i> be the length of this character sequence just prior to
- * execution of the {@code append} method. Then the character at index
- * <i>k</i> in the new character sequence is equal to the character at
- * index <i>k</i> in the old character sequence, if <i>k</i> is less than
- * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
- * in the argument {@code sb}.
- *
- * @param sb the {@code StringBuffer} to append.
- * @return a reference to this object.
- */
- public StringBuilder append(StringBuffer sb) {
- super.append(sb);
- return this;
- }
-
- @Override
- public StringBuilder append(CharSequence s) {
- super.append(s);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder append(CharSequence s, int start, int end) {
- super.append(s, start, end);
- return this;
- }
-
- @Override
- public StringBuilder append(char[] str) {
- super.append(str);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder append(char[] str, int offset, int len) {
- super.append(str, offset, len);
- return this;
- }
-
- @Override
- public StringBuilder append(boolean b) {
- super.append(b);
- return this;
- }
-
- @Override
- public StringBuilder append(char c) {
- super.append(c);
- return this;
- }
-
- @Override
- public StringBuilder append(int i) {
- super.append(i);
- return this;
- }
-
- @Override
- public StringBuilder append(long lng) {
- super.append(lng);
- return this;
- }
-
- @Override
- public StringBuilder append(float f) {
- super.append(f);
- return this;
- }
-
- @Override
- public StringBuilder append(double d) {
- super.append(d);
- return this;
- }
-
- /**
- * @since 1.5
- */
- @Override
- public StringBuilder appendCodePoint(int codePoint) {
- super.appendCodePoint(codePoint);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder delete(int start, int end) {
- super.delete(start, end);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder deleteCharAt(int index) {
- super.deleteCharAt(index);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder replace(int start, int end, String str) {
- super.replace(start, end, str);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int index, char[] str, int offset,
- int len)
- {
- super.insert(index, str, offset, len);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, Object obj) {
- super.insert(offset, obj);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, String str) {
- super.insert(offset, str);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, char[] str) {
- super.insert(offset, str);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int dstOffset, CharSequence s) {
- super.insert(dstOffset, s);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int dstOffset, CharSequence s,
- int start, int end)
- {
- super.insert(dstOffset, s, start, end);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, boolean b) {
- super.insert(offset, b);
- return this;
- }
-
- /**
- * @throws IndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, char c) {
- super.insert(offset, c);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, int i) {
- super.insert(offset, i);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, long l) {
- super.insert(offset, l);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, float f) {
- super.insert(offset, f);
- return this;
- }
-
- /**
- * @throws StringIndexOutOfBoundsException {@inheritDoc}
- */
- @Override
- public StringBuilder insert(int offset, double d) {
- super.insert(offset, d);
- return this;
- }
-
- @Override
- public int indexOf(String str) {
- return super.indexOf(str);
- }
-
- @Override
- public int indexOf(String str, int fromIndex) {
- return super.indexOf(str, fromIndex);
- }
-
- @Override
- public int lastIndexOf(String str) {
- return super.lastIndexOf(str);
- }
-
- @Override
- public int lastIndexOf(String str, int fromIndex) {
- return super.lastIndexOf(str, fromIndex);
- }
-
- @Override
- public StringBuilder reverse() {
- super.reverse();
- return this;
- }
-
- @Override
- public String toString() {
- // Create a copy, don't share the array
- return new String(value, 0, count);
- }
-
- /**
- * Save the state of the {@code StringBuilder} instance to a stream
- * (that is, serialize it).
- *
- * @serialData the number of characters currently stored in the string
- * builder ({@code int}), followed by the characters in the
- * string builder ({@code char[]}). The length of the
- * {@code char} array may be greater than the number of
- * characters currently stored in the string builder, in which
- * case extra characters are ignored.
- */
- private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException {
- s.defaultWriteObject();
- s.writeInt(count);
- s.writeObject(value);
- }
-
- /**
- * readObject is called to restore the state of the StringBuffer from
- * a stream.
- */
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- s.defaultReadObject();
- count = s.readInt();
- value = (char[]) s.readObject();
- }
-
- }
如何推导结论?
众所周知,static 的变量是线程之间共享的,加synchronized字段的方法和代码块在多线程调度中也能起到资源集中占用的优势。
结论:线程安全的就是独占的,所以效率上StringBuffer比StringBuilder的效率要高。