1. /*
  2. * @(#)StringBuilder.java 1.9 04/07/16
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.lang;
  8. import sun.misc.FloatingDecimal;
  9. /**
  10. * A mutable sequence of characters. This class provides an API compatible
  11. * with <code>StringBuffer</code>, but with no guarantee of synchronization.
  12. * This class is designed for use as a drop-in replacement for
  13. * <code>StringBuffer</code> in places where the string buffer was being
  14. * used by a single thread (as is generally the case). Where possible,
  15. * it is recommended that this class be used in preference to
  16. * <code>StringBuffer</code> as it will be faster under most implementations.
  17. *
  18. * <p>The principal operations on a <code>StringBuilder</code> are the
  19. * <code>append</code> and <code>insert</code> methods, which are
  20. * overloaded so as to accept data of any type. Each effectively
  21. * converts a given datum to a string and then appends or inserts the
  22. * characters of that string to the string builder. The
  23. * <code>append</code> method always adds these characters at the end
  24. * of the builder; the <code>insert</code> method adds the characters at
  25. * a specified point.
  26. * <p>
  27. * For example, if <code>z</code> refers to a string builder object
  28. * whose current contents are "<code>start</code>", then
  29. * the method call <code>z.append("le")</code> would cause the string
  30. * builder to contain "<code>startle</code>", whereas
  31. * <code>z.insert(4, "le")</code> would alter the string builder to
  32. * contain "<code>starlet</code>".
  33. * <p>
  34. * In general, if sb refers to an instance of a <code>StringBuilder</code>,
  35. * then <code>sb.append(x)</code> has the same effect as
  36. * <code>sb.insert(sb.length(), x)</code>.
  37. *
  38. * Every string builder has a capacity. As long as the length of the
  39. * character sequence contained in the string builder does not exceed
  40. * the capacity, it is not necessary to allocate a new internal
  41. * buffer. If the internal buffer overflows, it is automatically made larger.
  42. *
  43. * <p>Instances of <code>StringBuilder</code> are not safe for
  44. * use by multiple threads. If such synchronization is required then it is
  45. * recommended that {@link java.lang.StringBuffer} be used.
  46. *
  47. * @author Michael McCloskey
  48. * @version 1.9, 07/16/04
  49. * @see java.lang.StringBuffer
  50. * @see java.lang.String
  51. * @since 1.5
  52. */
  53. public final class StringBuilder
  54. extends AbstractStringBuilder
  55. implements java.io.Serializable, CharSequence
  56. {
  57. /** use serialVersionUID for interoperability */
  58. static final long serialVersionUID = 4383685877147921099L;
  59. /**
  60. * Constructs a string builder with no characters in it and an
  61. * initial capacity of 16 characters.
  62. */
  63. public StringBuilder() {
  64. super(16);
  65. }
  66. /**
  67. * Constructs a string builder with no characters in it and an
  68. * initial capacity specified by the <code>capacity</code> argument.
  69. *
  70. * @param capacity the initial capacity.
  71. * @throws NegativeArraySizeException if the <code>capacity</code>
  72. * argument is less than <code>0</code>.
  73. */
  74. public StringBuilder(int capacity) {
  75. super(capacity);
  76. }
  77. /**
  78. * Constructs a string builder initialized to the contents of the
  79. * specified string. The initial capacity of the string builder is
  80. * <code>16</code> plus the length of the string argument.
  81. *
  82. * @param str the initial contents of the buffer.
  83. * @throws NullPointerException if <code>str</code> is <code>null</code>
  84. */
  85. public StringBuilder(String str) {
  86. super(str.length() + 16);
  87. append(str);
  88. }
  89. /**
  90. * Constructs a string builder that contains the same characters
  91. * as the specified <code>CharSequence</code>. The initial capacity of
  92. * the string builder is <code>16</code> plus the length of the
  93. * <code>CharSequence</code> argument.
  94. *
  95. * @param seq the sequence to copy.
  96. * @throws NullPointerException if <code>seq</code> is <code>null</code>
  97. */
  98. public StringBuilder(CharSequence seq) {
  99. this(seq.length() + 16);
  100. append(seq);
  101. }
  102. /**
  103. * @see java.lang.String#valueOf(java.lang.Object)
  104. * @see #append(java.lang.String)
  105. */
  106. public StringBuilder append(Object obj) {
  107. return append(String.valueOf(obj));
  108. }
  109. public StringBuilder append(String str) {
  110. super.append(str);
  111. return this;
  112. }
  113. // Appends the specified string builder to this sequence.
  114. private StringBuilder append(StringBuilder sb) {
  115. if (sb == null)
  116. return append("null");
  117. int len = sb.length();
  118. int newcount = count + len;
  119. if (newcount > value.length)
  120. expandCapacity(newcount);
  121. sb.getChars(0, len, value, count);
  122. count = newcount;
  123. return this;
  124. }
  125. /**
  126. * Appends the specified <tt>StringBuffer</tt> to this sequence.
  127. * <p>
  128. * The characters of the <tt>StringBuffer</tt> argument are appended,
  129. * in order, to this sequence, increasing the
  130. * length of this sequence by the length of the argument.
  131. * If <tt>sb</tt> is <tt>null</tt>, then the four characters
  132. * <tt>"null"</tt> are appended to this sequence.
  133. * <p>
  134. * Let <i>n</i> be the length of this character sequence just prior to
  135. * execution of the <tt>append</tt> method. Then the character at index
  136. * <i>k</i> in the new character sequence is equal to the character at
  137. * index <i>k</i> in the old character sequence, if <i>k</i> is less than
  138. * <i>n</i> otherwise, it is equal to the character at index <i>k-n</i>
  139. * in the argument <code>sb</code>.
  140. *
  141. * @param sb the <tt>StringBuffer</tt> to append.
  142. * @return a reference to this object.
  143. */
  144. public StringBuilder append(StringBuffer sb) {
  145. super.append(sb);
  146. return this;
  147. }
  148. /**
  149. * @throws IndexOutOfBoundsException {@inheritDoc}
  150. */
  151. public StringBuilder append(CharSequence s) {
  152. if (s == null)
  153. s = "null";
  154. if (s instanceof String)
  155. return this.append((String)s);
  156. if (s instanceof StringBuffer)
  157. return this.append((StringBuffer)s);
  158. if (s instanceof StringBuilder)
  159. return this.append((StringBuilder)s);
  160. return this.append(s, 0, s.length());
  161. }
  162. /**
  163. * @throws IndexOutOfBoundsException {@inheritDoc}
  164. */
  165. public StringBuilder append(CharSequence s, int start, int end) {
  166. super.append(s, start, end);
  167. return this;
  168. }
  169. public StringBuilder append(char str[]) {
  170. super.append(str);
  171. return this;
  172. }
  173. public StringBuilder append(char str[], int offset, int len) {
  174. super.append(str, offset, len);
  175. return this;
  176. }
  177. /**
  178. * @see java.lang.String#valueOf(boolean)
  179. * @see #append(java.lang.String)
  180. */
  181. public StringBuilder append(boolean b) {
  182. super.append(b);
  183. return this;
  184. }
  185. public StringBuilder append(char c) {
  186. super.append(c);
  187. return this;
  188. }
  189. /**
  190. * @see java.lang.String#valueOf(int)
  191. * @see #append(java.lang.String)
  192. */
  193. public StringBuilder append(int i) {
  194. super.append(i);
  195. return this;
  196. }
  197. /**
  198. * @see java.lang.String#valueOf(long)
  199. * @see #append(java.lang.String)
  200. */
  201. public StringBuilder append(long lng) {
  202. super.append(lng);
  203. return this;
  204. }
  205. /**
  206. * @see java.lang.String#valueOf(float)
  207. * @see #append(java.lang.String)
  208. */
  209. public StringBuilder append(float f) {
  210. super.append(f);
  211. return this;
  212. }
  213. /**
  214. * @see java.lang.String#valueOf(double)
  215. * @see #append(java.lang.String)
  216. */
  217. public StringBuilder append(double d) {
  218. super.append(d);
  219. return this;
  220. }
  221. /**
  222. * @since 1.5
  223. */
  224. public StringBuilder appendCodePoint(int codePoint) {
  225. super.appendCodePoint(codePoint);
  226. return this;
  227. }
  228. /**
  229. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  230. */
  231. public StringBuilder delete(int start, int end) {
  232. super.delete(start, end);
  233. return this;
  234. }
  235. /**
  236. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  237. */
  238. public StringBuilder deleteCharAt(int index) {
  239. super.deleteCharAt(index);
  240. return this;
  241. }
  242. /**
  243. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  244. */
  245. public StringBuilder replace(int start, int end, String str) {
  246. super.replace(start, end, str);
  247. return this;
  248. }
  249. /**
  250. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  251. */
  252. public StringBuilder insert(int index, char str[], int offset,
  253. int len)
  254. {
  255. super.insert(index, str, offset, len);
  256. return this;
  257. }
  258. /**
  259. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  260. * @see java.lang.String#valueOf(java.lang.Object)
  261. * @see #insert(int, java.lang.String)
  262. * @see #length()
  263. */
  264. public StringBuilder insert(int offset, Object obj) {
  265. return insert(offset, String.valueOf(obj));
  266. }
  267. /**
  268. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  269. * @see #length()
  270. */
  271. public StringBuilder insert(int offset, String str) {
  272. super.insert(offset, str);
  273. return this;
  274. }
  275. /**
  276. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  277. */
  278. public StringBuilder insert(int offset, char str[]) {
  279. super.insert(offset, str);
  280. return this;
  281. }
  282. /**
  283. * @throws IndexOutOfBoundsException {@inheritDoc}
  284. */
  285. public StringBuilder insert(int dstOffset, CharSequence s) {
  286. if (s == null)
  287. s = "null";
  288. if (s instanceof String)
  289. return this.insert(dstOffset, (String)s);
  290. return this.insert(dstOffset, s, 0, s.length());
  291. }
  292. /**
  293. * @throws IndexOutOfBoundsException {@inheritDoc}
  294. */
  295. public StringBuilder insert(int dstOffset, CharSequence s,
  296. int start, int end)
  297. {
  298. super.insert(dstOffset, s, start, end);
  299. return this;
  300. }
  301. /**
  302. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  303. * @see java.lang.String#valueOf(boolean)
  304. * @see #insert(int, java.lang.String)
  305. * @see #length()
  306. */
  307. public StringBuilder insert(int offset, boolean b) {
  308. super.insert(offset, b);
  309. return this;
  310. }
  311. /**
  312. * @throws IndexOutOfBoundsException {@inheritDoc}
  313. * @see #length()
  314. */
  315. public StringBuilder insert(int offset, char c) {
  316. super.insert(offset, c);
  317. return this;
  318. }
  319. /**
  320. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  321. * @see java.lang.String#valueOf(int)
  322. * @see #insert(int, java.lang.String)
  323. * @see #length()
  324. */
  325. public StringBuilder insert(int offset, int i) {
  326. return insert(offset, String.valueOf(i));
  327. }
  328. /**
  329. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  330. * @see java.lang.String#valueOf(long)
  331. * @see #insert(int, java.lang.String)
  332. * @see #length()
  333. */
  334. public StringBuilder insert(int offset, long l) {
  335. return insert(offset, String.valueOf(l));
  336. }
  337. /**
  338. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  339. * @see java.lang.String#valueOf(float)
  340. * @see #insert(int, java.lang.String)
  341. * @see #length()
  342. */
  343. public StringBuilder insert(int offset, float f) {
  344. return insert(offset, String.valueOf(f));
  345. }
  346. /**
  347. * @throws StringIndexOutOfBoundsException {@inheritDoc}
  348. * @see java.lang.String#valueOf(double)
  349. * @see #insert(int, java.lang.String)
  350. * @see #length()
  351. */
  352. public StringBuilder insert(int offset, double d) {
  353. return insert(offset, String.valueOf(d));
  354. }
  355. /**
  356. * @throws NullPointerException {@inheritDoc}
  357. */
  358. public int indexOf(String str) {
  359. return indexOf(str, 0);
  360. }
  361. /**
  362. * @throws NullPointerException {@inheritDoc}
  363. */
  364. public int indexOf(String str, int fromIndex) {
  365. return String.indexOf(value, 0, count,
  366. str.toCharArray(), 0, str.length(), fromIndex);
  367. }
  368. /**
  369. * @throws NullPointerException {@inheritDoc}
  370. */
  371. public int lastIndexOf(String str) {
  372. return lastIndexOf(str, count);
  373. }
  374. /**
  375. * @throws NullPointerException {@inheritDoc}
  376. */
  377. public int lastIndexOf(String str, int fromIndex) {
  378. return String.lastIndexOf(value, 0, count,
  379. str.toCharArray(), 0, str.length(), fromIndex);
  380. }
  381. public StringBuilder reverse() {
  382. super.reverse();
  383. return this;
  384. }
  385. public String toString() {
  386. // Create a copy, don't share the array
  387. return new String(value, 0, count);
  388. }
  389. /**
  390. * Save the state of the <tt>StringBuilder</tt> instance to a stream
  391. * (that is, serialize it).
  392. *
  393. * @serialData the number of characters currently stored in the string
  394. * builder (<tt>int</tt>), followed by the characters in the
  395. * string builder (<tt>char[]</tt>). The length of the
  396. * <tt>char</tt> array may be greater than the number of
  397. * characters currently stored in the string builder, in which
  398. * case extra characters are ignored.
  399. */
  400. private void writeObject(java.io.ObjectOutputStream s)
  401. throws java.io.IOException {
  402. s.defaultWriteObject();
  403. s.writeInt(count);
  404. s.writeObject(value);
  405. }
  406. /**
  407. * readObject is called to restore the state of the StringBuffer from
  408. * a stream.
  409. */
  410. private void readObject(java.io.ObjectInputStream s)
  411. throws java.io.IOException, ClassNotFoundException {
  412. s.defaultReadObject();
  413. count = s.readInt();
  414. value = (char[]) s.readObject();
  415. }
  416. }