关键词搜索

源码搜索 ×
×

Java 字符串效率拼接测试报告—StringBuffer效率之王

发布2020-05-06浏览629次

详情内容

目录

实验报告

 测试代码

StringBuffer

StringBuilder

如何推导结论?


https://www.cnblogs.com/twzheng/p/5923642.html一文的结论进行验证。

发现效率StringBuilder和StringBuffer的结果是相反的,故此本文加以论证。 

实验报告

StringBuffer>StringBuilder>StringJoin>StringContact>StringPlus+

 测试代码

用其原文测试代码:

  1. public class StringUtilsTests {
  2. private static final int max = 1000000;
  3. @Test
  4. public void testPlus() {
  5. System.out.println(">>> testPlus() <<<");
  6. String str = "";
  7. long start = System.currentTimeMillis();
  8. for (int i = 0; i < max; i++) {
  9. str = str + "a";
  10. }
  11. long end = System.currentTimeMillis();
  12. long cost = end - start;
  13. System.out.println(" {str + \"a\"} cost=" + cost + " ms");
  14. }
  15. @Test
  16. public void testConcat() {
  17. System.out.println(">>> testConcat() <<<");
  18. String str = "";
  19. long start = System.currentTimeMillis();
  20. for (int i = 0; i < max; i++) {
  21. str = str.concat("a");
  22. }
  23. long end = System.currentTimeMillis();
  24. long cost = end - start;
  25. System.out.println(" {str.concat(\"a\")} cost=" + cost + " ms");
  26. }
  27. @Test
  28. public void testJoin() {
  29. System.out.println(">>> testJoin() <<<");
  30. long start = System.currentTimeMillis();
  31. List<String> list = new ArrayList<String>();
  32. for (int i = 0; i < max; i++) {
  33. list.add("a");
  34. }
  35. long end1 = System.currentTimeMillis();
  36. long cost1 = end1 - start;
  37. StringUtils.join(list, "");
  38. long end = System.currentTimeMillis();
  39. long cost = end - end1;
  40. System.out.println(" {list.add(\"a\")} cost1=" + cost1 + " ms");
  41. System.out.println(" {StringUtils.join(list, \"\")} cost=" + cost
  42. + " ms");
  43. }
  44. @Test
  45. public void testStringBuffer() {
  46. System.out.println(">>> testStringBuffer() <<<");
  47. long start = System.currentTimeMillis();
  48. StringBuffer strBuffer = new StringBuffer();
  49. for (int i = 0; i < max; i++) {
  50. strBuffer.append("a");
  51. }
  52. strBuffer.toString();
  53. long end = System.currentTimeMillis();
  54. long cost = end - start;
  55. System.out.println(" {strBuffer.append(\"a\")} cost=" + cost + " ms");
  56. }
  57. @Test
  58. public void testStringBuilder() {
  59. System.out.println(">>> testStringBuilder() <<<");
  60. long start = System.currentTimeMillis();
  61. StringBuilder strBuilder = new StringBuilder();
  62. for (int i = 0; i < max; i++) {
  63. strBuilder.append("a");
  64. }
  65. strBuilder.toString();
  66. long end = System.currentTimeMillis();
  67. long cost = end - start;
  68. System.out
  69. .println(" {strBuilder.append(\"a\")} cost=" + cost + " ms");
  70. }
  71. }

StringBuffer

我们重点看append的实现调用的是AbstractStringBuilder类方法:

  1. @Override
  2. public AbstractStringBuilder append(CharSequence s) {
  3. if (s == null)
  4. return appendNull();
  5. if (s instanceof String)
  6. return this.append((String)s);
  7. if (s instanceof AbstractStringBuilder)
  8. return this.append((AbstractStringBuilder)s);
  9. return this.append(s, 0, s.length());
  10. }

最终调用的是String的字符数组拷贝机制:

  1. /**
  2. * Copies characters from this string into the destination character
  3. * array.
  4. * <p>
  5. * The first character to be copied is at index {@code srcBegin};
  6. * the last character to be copied is at index {@code srcEnd-1}
  7. * (thus the total number of characters to be copied is
  8. * {@code srcEnd-srcBegin}). The characters are copied into the
  9. * subarray of {@code dst} starting at index {@code dstBegin}
  10. * and ending at index:
  11. * <blockquote><pre>
  12. * dstBegin + (srcEnd-srcBegin) - 1
  13. * </pre></blockquote>
  14. *
  15. * @param srcBegin index of the first character in the string
  16. * to copy.
  17. * @param srcEnd index after the last character in the string
  18. * to copy.
  19. * @param dst the destination array.
  20. * @param dstBegin the start offset in the destination array.
  21. * @exception IndexOutOfBoundsException If any of the following
  22. * is true:
  23. * <ul><li>{@code srcBegin} is negative.
  24. * <li>{@code srcBegin} is greater than {@code srcEnd}
  25. * <li>{@code srcEnd} is greater than the length of this
  26. * string
  27. * <li>{@code dstBegin} is negative
  28. * <li>{@code dstBegin+(srcEnd-srcBegin)} is larger than
  29. * {@code dst.length}</ul>
  30. */
  31. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
  32. if (srcBegin < 0) {
  33. throw new StringIndexOutOfBoundsException(srcBegin);
  34. }
  35. if (srcEnd > value.length) {
  36. throw new StringIndexOutOfBoundsException(srcEnd);
  37. }
  38. if (srcBegin > srcEnd) {
  39. throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
  40. }
  41. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  42. }

 StringBuffer源码:

  1. public final class StringBuffer
  2. extends AbstractStringBuilder
  3. implements java.io.Serializable, CharSequence
  4. {
  5. /**
  6. * A cache of the last value returned by toString. Cleared
  7. * whenever the StringBuffer is modified.
  8. */
  9. private transient char[] toStringCache;
  10. /** use serialVersionUID from JDK 1.0.2 for interoperability */
  11. static final long serialVersionUID = 3388685877147921107L;
  12. /**
  13. * Constructs a string buffer with no characters in it and an
  14. * initial capacity of 16 characters.
  15. */
  16. public StringBuffer() {
  17. super(16);
  18. }
  19. /**
  20. * Constructs a string buffer with no characters in it and
  21. * the specified initial capacity.
  22. *
  23. * @param capacity the initial capacity.
  24. * @exception NegativeArraySizeException if the {@code capacity}
  25. * argument is less than {@code 0}.
  26. */
  27. public StringBuffer(int capacity) {
  28. super(capacity);
  29. }
  30. /**
  31. * Constructs a string buffer initialized to the contents of the
  32. * specified string. The initial capacity of the string buffer is
  33. * {@code 16} plus the length of the string argument.
  34. *
  35. * @param str the initial contents of the buffer.
  36. */
  37. public StringBuffer(String str) {
  38. super(str.length() + 16);
  39. append(str);
  40. }
  41. /**
  42. * Constructs a string buffer that contains the same characters
  43. * as the specified {@code CharSequence}. The initial capacity of
  44. * the string buffer is {@code 16} plus the length of the
  45. * {@code CharSequence} argument.
  46. * <p>
  47. * If the length of the specified {@code CharSequence} is
  48. * less than or equal to zero, then an empty buffer of capacity
  49. * {@code 16} is returned.
  50. *
  51. * @param seq the sequence to copy.
  52. * @since 1.5
  53. */
  54. public StringBuffer(CharSequence seq) {
  55. this(seq.length() + 16);
  56. append(seq);
  57. }
  58. @Override
  59. public synchronized int length() {
  60. return count;
  61. }
  62. @Override
  63. public synchronized int capacity() {
  64. return value.length;
  65. }
  66. @Override
  67. public synchronized void ensureCapacity(int minimumCapacity) {
  68. super.ensureCapacity(minimumCapacity);
  69. }
  70. /**
  71. * @since 1.5
  72. */
  73. @Override
  74. public synchronized void trimToSize() {
  75. super.trimToSize();
  76. }
  77. /**
  78. * @throws IndexOutOfBoundsException {@inheritDoc}
  79. * @see #length()
  80. */
  81. @Override
  82. public synchronized void setLength(int newLength) {
  83. toStringCache = null;
  84. super.setLength(newLength);
  85. }
  86. /**
  87. * @throws IndexOutOfBoundsException {@inheritDoc}
  88. * @see #length()
  89. */
  90. @Override
  91. public synchronized char charAt(int index) {
  92. if ((index < 0) || (index >= count))
  93. throw new StringIndexOutOfBoundsException(index);
  94. return value[index];
  95. }
  96. /**
  97. * @since 1.5
  98. */
  99. @Override
  100. public synchronized int codePointAt(int index) {
  101. return super.codePointAt(index);
  102. }
  103. /**
  104. * @since 1.5
  105. */
  106. @Override
  107. public synchronized int codePointBefore(int index) {
  108. return super.codePointBefore(index);
  109. }
  110. /**
  111. * @since 1.5
  112. */
  113. @Override
  114. public synchronized int codePointCount(int beginIndex, int endIndex) {
  115. return super.codePointCount(beginIndex, endIndex);
  116. }
  117. /**
  118. * @since 1.5
  119. */
  120. @Override
  121. public synchronized int offsetByCodePoints(int index, int codePointOffset) {
  122. return super.offsetByCodePoints(index, codePointOffset);
  123. }
  124. /**
  125. * @throws IndexOutOfBoundsException {@inheritDoc}
  126. */
  127. @Override
  128. public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
  129. int dstBegin)
  130. {
  131. super.getChars(srcBegin, srcEnd, dst, dstBegin);
  132. }
  133. /**
  134. * @throws IndexOutOfBoundsException {@inheritDoc}
  135. * @see #length()
  136. */
  137. @Override
  138. public synchronized void setCharAt(int index, char ch) {
  139. if ((index < 0) || (index >= count))
  140. throw new StringIndexOutOfBoundsException(index);
  141. toStringCache = null;
  142. value[index] = ch;
  143. }
  144. @Override
  145. public synchronized StringBuffer append(Object obj) {
  146. toStringCache = null;
  147. super.append(String.valueOf(obj));
  148. return this;
  149. }
  150. @Override
  151. public synchronized StringBuffer append(String str) {
  152. toStringCache = null;
  153. super.append(str);
  154. return this;
  155. }
  156. /**
  157. * Appends the specified {@code StringBuffer} to this sequence.
  158. * <p>
  159. * The characters of the {@code StringBuffer} argument are appended,
  160. * in order, to the contents of this {@code StringBuffer}, increasing the
  161. * length of this {@code StringBuffer} by the length of the argument.
  162. * If {@code sb} is {@code null}, then the four characters
  163. * {@code "null"} are appended to this {@code StringBuffer}.
  164. * <p>
  165. * Let <i>n</i> be the length of the old character sequence, the one
  166. * contained in the {@code StringBuffer} just prior to execution of the
  167. * {@code append} method. Then the character at index <i>k</i> in
  168. * the new character sequence is equal to the character at index <i>k</i>
  169. * in the old character sequence, if <i>k</i> is less than <i>n</i>;
  170. * otherwise, it is equal to the character at index <i>k-n</i> in the
  171. * argument {@code sb}.
  172. * <p>
  173. * This method synchronizes on {@code this}, the destination
  174. * object, but does not synchronize on the source ({@code sb}).
  175. *
  176. * @param sb the {@code StringBuffer} to append.
  177. * @return a reference to this object.
  178. * @since 1.4
  179. */
  180. public synchronized StringBuffer append(StringBuffer sb) {
  181. toStringCache = null;
  182. super.append(sb);
  183. return this;
  184. }
  185. /**
  186. * @since 1.8
  187. */
  188. @Override
  189. synchronized StringBuffer append(AbstractStringBuilder asb) {
  190. toStringCache = null;
  191. super.append(asb);
  192. return this;
  193. }
  194. /**
  195. * Appends the specified {@code CharSequence} to this
  196. * sequence.
  197. * <p>
  198. * The characters of the {@code CharSequence} argument are appended,
  199. * in order, increasing the length of this sequence by the length of the
  200. * argument.
  201. *
  202. * <p>The result of this method is exactly the same as if it were an
  203. * invocation of this.append(s, 0, s.length());
  204. *
  205. * <p>This method synchronizes on {@code this}, the destination
  206. * object, but does not synchronize on the source ({@code s}).
  207. *
  208. * <p>If {@code s} is {@code null}, then the four characters
  209. * {@code "null"} are appended.
  210. *
  211. * @param s the {@code CharSequence} to append.
  212. * @return a reference to this object.
  213. * @since 1.5
  214. */
  215. @Override
  216. public synchronized StringBuffer append(CharSequence s) {
  217. toStringCache = null;
  218. super.append(s);
  219. return this;
  220. }
  221. /**
  222. * @throws IndexOutOfBoundsException {@inheritDoc}
  223. * @since 1.5
  224. */
  225. @Override
  226. public synchronized StringBuffer append(CharSequence s, int start, int end)
  227. {
  228. toStringCache = null;
  229. super.append(s, start, end);
  230. return this;
  231. }
  232. @Override
  233. public synchronized StringBuffer append(char[] str) {
  234. toStringCache = null;
  235. super.append(str);
  236. return this;
  237. }
  238. /**
  239. * @throws IndexOutOfBoundsException {@inheritDoc}
  240. */
  241. @Override
  242. public synchronized StringBuffer append(char[] str, int offset, int len) {
  243. toStringCache = null;
  244. super.append(str, offset, len);
  245. return this;
  246. }
  247. @Override
  248. public synchronized StringBuffer append(boolean b) {
  249. toStringCache = null;
  250. super.append(b);
  251. return this;
  252. }
  253. @Override
  254. public synchronized StringBuffer append(char c) {
  255. toStringCache = null;
  256. super.append(c);
  257. return this;
  258. }
  259. @Override
  260. public synchronized StringBuffer append(int i) {
  261. toStringCache = null;
  262. super.append(i);
  263. return this;
  264. }
  265. /**
  266. * @since 1.5
  267. */
  268. @Override
  269. public synchronized StringBuffer appendCodePoint(int codePoint) {
  270. toStringCache = null;
  271. super.appendCodePoint(codePoint);
  272. return this;
  273. }
  274. @Override
  275. public synchronized StringBuffer append(long lng) {
  276. toStringCache = null;
  277. super.append(lng);
  278. return this;
  279. }
  280. @Override
  281. public synchronized StringBuffer append(float f) {
  282. toStringCache = null;
  283. super.append(f);
  284. return this;
  285. }
  286. @Override
  287. public synchronized StringBuffer append(double d) {
  288. toStringCache = null;
  289. super.append(d);
  290. return this;
  291. }
  292. /**
  293. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  294. * @since 1.2
  295. */
  296. @Override
  297. public synchronized StringBuffer delete(int start, int end) {
  298. toStringCache = null;
  299. super.delete(start, end);
  300. return this;
  301. }
  302. /**
  303. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  304. * @since 1.2
  305. */
  306. @Override
  307. public synchronized StringBuffer deleteCharAt(int index) {
  308. toStringCache = null;
  309. super.deleteCharAt(index);
  310. return this;
  311. }
  312. /**
  313. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  314. * @since 1.2
  315. */
  316. @Override
  317. public synchronized StringBuffer replace(int start, int end, String str) {
  318. toStringCache = null;
  319. super.replace(start, end, str);
  320. return this;
  321. }
  322. /**
  323. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  324. * @since 1.2
  325. */
  326. @Override
  327. public synchronized String substring(int start) {
  328. return substring(start, count);
  329. }
  330. /**
  331. * @throws IndexOutOfBoundsException {@inheritDoc}
  332. * @since 1.4
  333. */
  334. @Override
  335. public synchronized CharSequence subSequence(int start, int end) {
  336. return super.substring(start, end);
  337. }
  338. /**
  339. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  340. * @since 1.2
  341. */
  342. @Override
  343. public synchronized String substring(int start, int end) {
  344. return super.substring(start, end);
  345. }
  346. /**
  347. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  348. * @since 1.2
  349. */
  350. @Override
  351. public synchronized StringBuffer insert(int index, char[] str, int offset,
  352. int len)
  353. {
  354. toStringCache = null;
  355. super.insert(index, str, offset, len);
  356. return this;
  357. }
  358. /**
  359. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  360. */
  361. @Override
  362. public synchronized StringBuffer insert(int offset, Object obj) {
  363. toStringCache = null;
  364. super.insert(offset, String.valueOf(obj));
  365. return this;
  366. }
  367. /**
  368. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  369. */
  370. @Override
  371. public synchronized StringBuffer insert(int offset, String str) {
  372. toStringCache = null;
  373. super.insert(offset, str);
  374. return this;
  375. }
  376. /**
  377. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  378. */
  379. @Override
  380. public synchronized StringBuffer insert(int offset, char[] str) {
  381. toStringCache = null;
  382. super.insert(offset, str);
  383. return this;
  384. }
  385. /**
  386. * @throws IndexOutOfBoundsException {@inheritDoc}
  387. * @since 1.5
  388. */
  389. @Override
  390. public StringBuffer insert(int dstOffset, CharSequence s) {
  391. // Note, synchronization achieved via invocations of other StringBuffer methods
  392. // after narrowing of s to specific type
  393. // Ditto for toStringCache clearing
  394. super.insert(dstOffset, s);
  395. return this;
  396. }
  397. /**
  398. * @throws IndexOutOfBoundsException {@inheritDoc}
  399. * @since 1.5
  400. */
  401. @Override
  402. public synchronized StringBuffer insert(int dstOffset, CharSequence s,
  403. int start, int end)
  404. {
  405. toStringCache = null;
  406. super.insert(dstOffset, s, start, end);
  407. return this;
  408. }
  409. /**
  410. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  411. */
  412. @Override
  413. public StringBuffer insert(int offset, boolean b) {
  414. // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
  415. // after conversion of b to String by super class method
  416. // Ditto for toStringCache clearing
  417. super.insert(offset, b);
  418. return this;
  419. }
  420. /**
  421. * @throws IndexOutOfBoundsException {@inheritDoc}
  422. */
  423. @Override
  424. public synchronized StringBuffer insert(int offset, char c) {
  425. toStringCache = null;
  426. super.insert(offset, c);
  427. return this;
  428. }
  429. /**
  430. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  431. */
  432. @Override
  433. public StringBuffer insert(int offset, int i) {
  434. // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
  435. // after conversion of i to String by super class method
  436. // Ditto for toStringCache clearing
  437. super.insert(offset, i);
  438. return this;
  439. }
  440. /**
  441. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  442. */
  443. @Override
  444. public StringBuffer insert(int offset, long l) {
  445. // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
  446. // after conversion of l to String by super class method
  447. // Ditto for toStringCache clearing
  448. super.insert(offset, l);
  449. return this;
  450. }
  451. /**
  452. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  453. */
  454. @Override
  455. public StringBuffer insert(int offset, float f) {
  456. // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
  457. // after conversion of f to String by super class method
  458. // Ditto for toStringCache clearing
  459. super.insert(offset, f);
  460. return this;
  461. }
  462. /**
  463. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  464. */
  465. @Override
  466. public StringBuffer insert(int offset, double d) {
  467. // Note, synchronization achieved via invocation of StringBuffer insert(int, String)
  468. // after conversion of d to String by super class method
  469. // Ditto for toStringCache clearing
  470. super.insert(offset, d);
  471. return this;
  472. }
  473. /**
  474. * @since 1.4
  475. */
  476. @Override
  477. public int indexOf(String str) {
  478. // Note, synchronization achieved via invocations of other StringBuffer methods
  479. return super.indexOf(str);
  480. }
  481. /**
  482. * @since 1.4
  483. */
  484. @Override
  485. public synchronized int indexOf(String str, int fromIndex) {
  486. return super.indexOf(str, fromIndex);
  487. }
  488. /**
  489. * @since 1.4
  490. */
  491. @Override
  492. public int lastIndexOf(String str) {
  493. // Note, synchronization achieved via invocations of other StringBuffer methods
  494. return lastIndexOf(str, count);
  495. }
  496. /**
  497. * @since 1.4
  498. */
  499. @Override
  500. public synchronized int lastIndexOf(String str, int fromIndex) {
  501. return super.lastIndexOf(str, fromIndex);
  502. }
  503. /**
  504. * @since JDK1.0.2
  505. */
  506. @Override
  507. public synchronized StringBuffer reverse() {
  508. toStringCache = null;
  509. super.reverse();
  510. return this;
  511. }
  512. @Override
  513. public synchronized String toString() {
  514. if (toStringCache == null) {
  515. toStringCache = Arrays.copyOfRange(value, 0, count);
  516. }
  517. return new String(toStringCache, true);
  518. }
  519. /**
  520. * Serializable fields for StringBuffer.
  521. *
  522. * @serialField value char[]
  523. * The backing character array of this StringBuffer.
  524. * @serialField count int
  525. * The number of characters in this StringBuffer.
  526. * @serialField shared boolean
  527. * A flag indicating whether the backing array is shared.
  528. * The value is ignored upon deserialization.
  529. */
  530. private static final java.io.ObjectStreamField[] serialPersistentFields =
  531. {
  532. new java.io.ObjectStreamField("value", char[].class),
  533. new java.io.ObjectStreamField("count", Integer.TYPE),
  534. new java.io.ObjectStreamField("shared", Boolean.TYPE),
  535. };
  536. /**
  537. * readObject is called to restore the state of the StringBuffer from
  538. * a stream.
  539. */
  540. private synchronized void writeObject(java.io.ObjectOutputStream s)
  541. throws java.io.IOException {
  542. java.io.ObjectOutputStream.PutField fields = s.putFields();
  543. fields.put("value", value);
  544. fields.put("count", count);
  545. fields.put("shared", false);
  546. s.writeFields();
  547. }
  548. /**
  549. * readObject is called to restore the state of the StringBuffer from
  550. * a stream.
  551. */
  552. private void readObject(java.io.ObjectInputStream s)
  553. throws java.io.IOException, ClassNotFoundException {
  554. java.io.ObjectInputStream.GetField fields = s.readFields();
  555. value = (char[])fields.get("value", null);
  556. count = fields.get("count", 0);
  557. }
  558. }

StringBuilder

StringBuilder的实现与StringBuffer代码上差不多,但StringBuffer是使用了锁是线程安全的。

  1. public final class StringBuilder
  2. extends AbstractStringBuilder
  3. implements java.io.Serializable, CharSequence
  4. {
  5. /** use serialVersionUID for interoperability */
  6. static final long serialVersionUID = 4383685877147921099L;
  7. /**
  8. * Constructs a string builder with no characters in it and an
  9. * initial capacity of 16 characters.
  10. */
  11. public StringBuilder() {
  12. super(16);
  13. }
  14. /**
  15. * Constructs a string builder with no characters in it and an
  16. * initial capacity specified by the {@code capacity} argument.
  17. *
  18. * @param capacity the initial capacity.
  19. * @throws NegativeArraySizeException if the {@code capacity}
  20. * argument is less than {@code 0}.
  21. */
  22. public StringBuilder(int capacity) {
  23. super(capacity);
  24. }
  25. /**
  26. * Constructs a string builder initialized to the contents of the
  27. * specified string. The initial capacity of the string builder is
  28. * {@code 16} plus the length of the string argument.
  29. *
  30. * @param str the initial contents of the buffer.
  31. */
  32. public StringBuilder(String str) {
  33. super(str.length() + 16);
  34. append(str);
  35. }
  36. /**
  37. * Constructs a string builder that contains the same characters
  38. * as the specified {@code CharSequence}. The initial capacity of
  39. * the string builder is {@code 16} plus the length of the
  40. * {@code CharSequence} argument.
  41. *
  42. * @param seq the sequence to copy.
  43. */
  44. public StringBuilder(CharSequence seq) {
  45. this(seq.length() + 16);
  46. append(seq);
  47. }
  48. @Override
  49. public StringBuilder append(Object obj) {
  50. return append(String.valueOf(obj));
  51. }
  52. @Override
  53. public StringBuilder append(String str) {
  54. super.append(str);
  55. return this;
  56. }
  57. /**
  58. * Appends the specified {@code StringBuffer} to this sequence.
  59. * <p>
  60. * The characters of the {@code StringBuffer} argument are appended,
  61. * in order, to this sequence, increasing the
  62. * length of this sequence by the length of the argument.
  63. * If {@code sb} is {@code null}, then the four characters
  64. * {@code "null"} are appended to this sequence.
  65. * <p>
  66. * Let <i>n</i> be the length of this character sequence just prior to
  67. * execution of the {@code append} method. Then the character at index
  68. * <i>k</i> in the new character sequence is equal to the character at
  69. * index <i>k</i> in the old character sequence, if <i>k</i> is less than
  70. * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
  71. * in the argument {@code sb}.
  72. *
  73. * @param sb the {@code StringBuffer} to append.
  74. * @return a reference to this object.
  75. */
  76. public StringBuilder append(StringBuffer sb) {
  77. super.append(sb);
  78. return this;
  79. }
  80. @Override
  81. public StringBuilder append(CharSequence s) {
  82. super.append(s);
  83. return this;
  84. }
  85. /**
  86. * @throws IndexOutOfBoundsException {@inheritDoc}
  87. */
  88. @Override
  89. public StringBuilder append(CharSequence s, int start, int end) {
  90. super.append(s, start, end);
  91. return this;
  92. }
  93. @Override
  94. public StringBuilder append(char[] str) {
  95. super.append(str);
  96. return this;
  97. }
  98. /**
  99. * @throws IndexOutOfBoundsException {@inheritDoc}
  100. */
  101. @Override
  102. public StringBuilder append(char[] str, int offset, int len) {
  103. super.append(str, offset, len);
  104. return this;
  105. }
  106. @Override
  107. public StringBuilder append(boolean b) {
  108. super.append(b);
  109. return this;
  110. }
  111. @Override
  112. public StringBuilder append(char c) {
  113. super.append(c);
  114. return this;
  115. }
  116. @Override
  117. public StringBuilder append(int i) {
  118. super.append(i);
  119. return this;
  120. }
  121. @Override
  122. public StringBuilder append(long lng) {
  123. super.append(lng);
  124. return this;
  125. }
  126. @Override
  127. public StringBuilder append(float f) {
  128. super.append(f);
  129. return this;
  130. }
  131. @Override
  132. public StringBuilder append(double d) {
  133. super.append(d);
  134. return this;
  135. }
  136. /**
  137. * @since 1.5
  138. */
  139. @Override
  140. public StringBuilder appendCodePoint(int codePoint) {
  141. super.appendCodePoint(codePoint);
  142. return this;
  143. }
  144. /**
  145. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  146. */
  147. @Override
  148. public StringBuilder delete(int start, int end) {
  149. super.delete(start, end);
  150. return this;
  151. }
  152. /**
  153. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  154. */
  155. @Override
  156. public StringBuilder deleteCharAt(int index) {
  157. super.deleteCharAt(index);
  158. return this;
  159. }
  160. /**
  161. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  162. */
  163. @Override
  164. public StringBuilder replace(int start, int end, String str) {
  165. super.replace(start, end, str);
  166. return this;
  167. }
  168. /**
  169. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  170. */
  171. @Override
  172. public StringBuilder insert(int index, char[] str, int offset,
  173. int len)
  174. {
  175. super.insert(index, str, offset, len);
  176. return this;
  177. }
  178. /**
  179. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  180. */
  181. @Override
  182. public StringBuilder insert(int offset, Object obj) {
  183. super.insert(offset, obj);
  184. return this;
  185. }
  186. /**
  187. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  188. */
  189. @Override
  190. public StringBuilder insert(int offset, String str) {
  191. super.insert(offset, str);
  192. return this;
  193. }
  194. /**
  195. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  196. */
  197. @Override
  198. public StringBuilder insert(int offset, char[] str) {
  199. super.insert(offset, str);
  200. return this;
  201. }
  202. /**
  203. * @throws IndexOutOfBoundsException {@inheritDoc}
  204. */
  205. @Override
  206. public StringBuilder insert(int dstOffset, CharSequence s) {
  207. super.insert(dstOffset, s);
  208. return this;
  209. }
  210. /**
  211. * @throws IndexOutOfBoundsException {@inheritDoc}
  212. */
  213. @Override
  214. public StringBuilder insert(int dstOffset, CharSequence s,
  215. int start, int end)
  216. {
  217. super.insert(dstOffset, s, start, end);
  218. return this;
  219. }
  220. /**
  221. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  222. */
  223. @Override
  224. public StringBuilder insert(int offset, boolean b) {
  225. super.insert(offset, b);
  226. return this;
  227. }
  228. /**
  229. * @throws IndexOutOfBoundsException {@inheritDoc}
  230. */
  231. @Override
  232. public StringBuilder insert(int offset, char c) {
  233. super.insert(offset, c);
  234. return this;
  235. }
  236. /**
  237. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  238. */
  239. @Override
  240. public StringBuilder insert(int offset, int i) {
  241. super.insert(offset, i);
  242. return this;
  243. }
  244. /**
  245. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  246. */
  247. @Override
  248. public StringBuilder insert(int offset, long l) {
  249. super.insert(offset, l);
  250. return this;
  251. }
  252. /**
  253. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  254. */
  255. @Override
  256. public StringBuilder insert(int offset, float f) {
  257. super.insert(offset, f);
  258. return this;
  259. }
  260. /**
  261. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  262. */
  263. @Override
  264. public StringBuilder insert(int offset, double d) {
  265. super.insert(offset, d);
  266. return this;
  267. }
  268. @Override
  269. public int indexOf(String str) {
  270. return super.indexOf(str);
  271. }
  272. @Override
  273. public int indexOf(String str, int fromIndex) {
  274. return super.indexOf(str, fromIndex);
  275. }
  276. @Override
  277. public int lastIndexOf(String str) {
  278. return super.lastIndexOf(str);
  279. }
  280. @Override
  281. public int lastIndexOf(String str, int fromIndex) {
  282. return super.lastIndexOf(str, fromIndex);
  283. }
  284. @Override
  285. public StringBuilder reverse() {
  286. super.reverse();
  287. return this;
  288. }
  289. @Override
  290. public String toString() {
  291. // Create a copy, don't share the array
  292. return new String(value, 0, count);
  293. }
  294. /**
  295. * Save the state of the {@code StringBuilder} instance to a stream
  296. * (that is, serialize it).
  297. *
  298. * @serialData the number of characters currently stored in the string
  299. * builder ({@code int}), followed by the characters in the
  300. * string builder ({@code char[]}). The length of the
  301. * {@code char} array may be greater than the number of
  302. * characters currently stored in the string builder, in which
  303. * case extra characters are ignored.
  304. */
  305. private void writeObject(java.io.ObjectOutputStream s)
  306. throws java.io.IOException {
  307. s.defaultWriteObject();
  308. s.writeInt(count);
  309. s.writeObject(value);
  310. }
  311. /**
  312. * readObject is called to restore the state of the StringBuffer from
  313. * a stream.
  314. */
  315. private void readObject(java.io.ObjectInputStream s)
  316. throws java.io.IOException, ClassNotFoundException {
  317. s.defaultReadObject();
  318. count = s.readInt();
  319. value = (char[]) s.readObject();
  320. }
  321. }

如何推导结论?

众所周知,static 的变量是线程之间共享的,加synchronized字段的方法和代码块在多线程调度中也能起到资源集中占用的优势。

结论:线程安全的就是独占的,所以效率上StringBuffer比StringBuilder的效率要高。

相关技术文章

点击QQ咨询
开通会员
返回顶部
×
微信扫码支付
微信扫码支付
确定支付下载
请使用微信描二维码支付
×

提示信息

×

选择支付方式

  • 微信支付
  • 支付宝付款
确定支付下载