001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.lang;
019:
020: import java.io.IOException;
021: import java.io.ObjectInputStream;
022: import java.io.ObjectOutputStream;
023: import java.io.Serializable;
024:
025: /**
026: * <p>
027: * A modifiable {@link CharSequence sequence of characters} for use in creating
028: * and modifying Strings. This class is intended as a direct replacement of
029: * {@link java.lang.StringBuffer} for non-concurrent use; unlike
030: * <code>StringBuffer</code> this class is not synchronized for thread safety.
031: * </p>
032: *
033: * <p>
034: * The majority of the modification methods on this class return
035: * <code>StringBuilder</code>, so that, like <code>StringBuffer</code>s,
036: * they can be used in chaining method calls together. For example,
037: * <code>new StringBuilder("One should ").append("always strive ").append("to achieve Harmony")</code>.
038: * </p>
039: *
040: * @see java.lang.CharSequence
041: * @see java.lang.Appendable
042: * @see java.lang.StringBuffer
043: * @see java.lang.String
044: *
045: * @since 1.5
046: */
047: public final class StringBuilder extends AbstractStringBuilder
048: implements Appendable, CharSequence, Serializable {
049:
050: private static final long serialVersionUID = 4383685877147921099L;
051:
052: /**
053: * <p>
054: * Constructs an instance with an initial capacity of <code>16</code>.
055: * </p>
056: *
057: * @see #capacity()
058: */
059: public StringBuilder() {
060: super ();
061: }
062:
063: /**
064: * <p>
065: * Constructs an instance with a specified capacity.
066: * </p>
067: *
068: * @param capacity The initial capacity to use.
069: *
070: * @throws NegativeArraySizeException if the <code>capacity</code>
071: * parameter is <code>null</code>.
072: *
073: * @see #capacity()
074: */
075: public StringBuilder(int capacity) {
076: super (capacity);
077: }
078:
079: /**
080: * <p>
081: * Constructs an instance that's populated by a {@link CharSequence}. The
082: * capacity of the new builder will bee the length of the
083: * <code>CharSequence</code> plus 16.
084: * </p>
085: *
086: * @param seq The <code>CharSequence</code> to copy into the builder.
087: * @throws NullPointerException if the <code>seq</code> parameter is
088: * <code>null</code>.
089: */
090: public StringBuilder(CharSequence seq) {
091: super (seq.toString());
092: }
093:
094: /**
095: * <p>
096: * Constructs an instance that's populated by a {@link String}. The
097: * capacity of the new builder will bee the length of the
098: * <code>String</code> plus 16.
099: * </p>
100: *
101: * @param str The <code>String</code> to copy into the builder.
102: * @throws NullPointerException if the <code>str</code> parameter is
103: * <code>null</code>.
104: */
105: public StringBuilder(String str) {
106: super (str);
107: }
108:
109: /**
110: * <p>
111: * Appends the String representation of the <code>boolean</code> value
112: * passed. The <code>boolean</code> value is converted to a String
113: * according to the rule defined by {@link String#valueOf(boolean)}.
114: * </p>
115: *
116: * @param b The <code>boolean</code> value to append to this object.
117: * @return A reference to this object.
118: *
119: * @see String#valueOf(boolean)
120: */
121: public StringBuilder append(boolean b) {
122: append0(b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
123: return this ;
124: }
125:
126: /**
127: * <p>
128: * Appends the String representation of the <code>char</code> value
129: * passed. The <code>char</code> value is converted to a String according
130: * to the rule defined by {@link String#valueOf(char)}.
131: * </p>
132: *
133: * @param c The <code>char</code> value to append to this object.
134: * @return A reference to this object.
135: *
136: * @see String#valueOf(char)
137: */
138: public StringBuilder append(char c) {
139: append0(c);
140: return this ;
141: }
142:
143: /**
144: * <p>
145: * Appends the String representation of the <code>int</code> value passed.
146: * The <code>int</code> value is converted to a String according to the
147: * rule defined by {@link String#valueOf(int)}.
148: * </p>
149: *
150: * @param i The <code>int</code> value to append to this object.
151: * @return A reference to this object.
152: *
153: * @see String#valueOf(int)
154: */
155: public StringBuilder append(int i) {
156: append0(Integer.toString(i));
157: return this ;
158: }
159:
160: /**
161: * <p>
162: * Appends the String representation of the <code>long</code> value
163: * passed. The <code>long</code> value is converted to a String according
164: * to the rule defined by {@link String#valueOf(long)}.
165: * </p>
166: *
167: * @param lng The <code>long</code> value to append to this object.
168: * @return A reference to this object.
169: *
170: * @see String#valueOf(long)
171: */
172: public StringBuilder append(long lng) {
173: append0(Long.toString(lng));
174: return this ;
175: }
176:
177: /**
178: * <p>
179: * Appends the String representation of the <code>float</code> value
180: * passed. The <code>float</code> value is converted to a String according
181: * to the rule defined by {@link String#valueOf(float)}.
182: * </p>
183: *
184: * @param f The <code>float</code> value to append to this object.
185: * @return A reference to this object.
186: *
187: * @see String#valueOf(float)
188: */
189: public StringBuilder append(float f) {
190: append0(Float.toString(f));
191: return this ;
192: }
193:
194: /**
195: * <p>
196: * Appends the String representation of the <code>double</code> value
197: * passed. The <code>double</code> value is converted to a String
198: * according to the rule defined by {@link String#valueOf(double)}.
199: * </p>
200: *
201: * @param d The <code>double</code> value to append to this object.
202: * @return A reference to this object.
203: *
204: * @see String#valueOf(double)
205: */
206: public StringBuilder append(double d) {
207: append0(Double.toString(d));
208: return this ;
209: }
210:
211: /**
212: * <p>
213: * Appends the String representation of the <code>Object</code> value
214: * passed. The <code>Object</code> value is converted to a String
215: * according to the rule defined by {@link String#valueOf(Object)}.
216: * </p>
217: *
218: * @param obj The <code>Object</code> value to append to this object.
219: * @return A reference to this object.
220: *
221: * @see String#valueOf(Object)
222: */
223: public StringBuilder append(Object obj) {
224: if (obj == null) {
225: appendNull();
226: } else {
227: append0(obj.toString());
228: }
229: return this ;
230: }
231:
232: /**
233: * <p>
234: * Appends the contents of the String. If the String passed is
235: * <code>null</code>, then the String <code>"null"</code> is appended.
236: * </p>
237: *
238: * @param str The String to append to this object.
239: * @return A reference to this object.
240: */
241: public StringBuilder append(String str) {
242: append0(str);
243: return this ;
244: }
245:
246: /**
247: * <p>
248: * Appends the contents of the StringBuffer. If the StringBuffer passed is
249: * <code>null</code>, then the StringBuffer <code>"null"</code> is
250: * appended.
251: * </p>
252: *
253: * @param sb The StringBuffer to append to this object.
254: * @return A reference to this object.
255: */
256: public StringBuilder append(StringBuffer sb) {
257: if (sb == null) {
258: appendNull();
259: } else {
260: append0(sb.getValue(), 0, sb.length());
261: }
262: return this ;
263: }
264:
265: /**
266: * <p>
267: * Appends the String representation of the <code>char[]</code> value
268: * passed. The <code>char[]</code> value is converted to a String
269: * according to the rule defined by {@link String#valueOf(char[])}.
270: * </p>
271: *
272: * @param ch The <code>char[]</code> value to append to this object.
273: * @return A reference to this object.
274: *
275: * @see String#valueOf(char[])
276: */
277: public StringBuilder append(char[] ch) {
278: append0(ch);
279: return this ;
280: }
281:
282: /**
283: * <p>
284: * Appends the String representation of the subset of the
285: * <code>char[]</code> value passed. The <code>char[]</code> value is
286: * converted to a String according to the rule defined by
287: * {@link String#valueOf(char[],int,int)}.
288: * </p>
289: *
290: * @param str The <code>char[]</code> value to append to this object.
291: * @param offset The inclusive offset index to begin copying from the
292: * <code>str</code> parameter.
293: * @param len The number of character to copy from the <code>str</code>
294: * parameter.
295: * @return A reference to this object.
296: *
297: * @see String#valueOf(char[],int,int)
298: */
299: public StringBuilder append(char[] str, int offset, int len) {
300: append0(str, offset, len);
301: return this ;
302: }
303:
304: /**
305: * <p>
306: * Appends the String representation of the <code>CharSequence</code>
307: * value passed. If the <code>CharSequence</code> is <code>null</code>,
308: * then the String <code>"null"</code> is appended.
309: * </p>
310: *
311: * @param csq The <code>CharSequence</code> value to append to this
312: * object.
313: * @return A reference to this object.
314: */
315: public StringBuilder append(CharSequence csq) {
316: if (csq == null) {
317: appendNull();
318: } else {
319: append0(csq.toString());
320: }
321: return this ;
322: }
323:
324: /**
325: * <p>
326: * Appends the String representation of the subsequence of the
327: * <code>CharSequence</code> value passed. If the
328: * <code>CharSequence</code> is <code>null</code>, then the String
329: * <code>"null"</code> is used to extract the subsequence from.
330: * </p>
331: *
332: * @param csq The <code>CharSequence</code> value to append to this
333: * object.
334: * @param start The beginning index of the subsequence.
335: * @param end The ending index of the subsequence.
336: * @return A reference to this object.
337: */
338: public StringBuilder append(CharSequence csq, int start, int end) {
339: append0(csq, start, end);
340: return this ;
341: }
342:
343: /**
344: * <p>
345: * Appends the encoded Unicode code point to this object. The code point is
346: * converted to a <code>char[]</code> as defined by
347: * {@link Character#toChars(int)}.
348: * </p>
349: *
350: * @param codePoint The Unicode code point to encode and append.
351: * @return A reference to this object.
352: * @see Character#toChars(int)
353: */
354: public StringBuilder appendCodePoint(int codePoint) {
355: append0(Character.toChars(codePoint));
356: return this ;
357: }
358:
359: /**
360: * <p>
361: * Deletes a sequence of characters within this object, shifts any remaining
362: * characters to the left and adjusts the {@link #length()} of this object.
363: * </p>
364: *
365: * @param start The inclusive start index to begin deletion.
366: * @param end The exclusive end index to stop deletion.
367: * @return A reference to this object.
368: * @throws StringIndexOutOfBoundsException if <code>start</code> is less
369: * than zero, greater than the current length or greater than
370: * <code>end</code>.
371: */
372: public StringBuilder delete(int start, int end) {
373: delete0(start, end);
374: return this ;
375: }
376:
377: /**
378: * <p>
379: * Deletes a single character within this object, shifts any remaining
380: * characters to the left and adjusts the {@link #length()} of this object.
381: * </p>
382: *
383: * @param index The index of the character to delete.
384: * @return A reference to this object.
385: * @throws StringIndexOutOfBoundsException if <code>index</code> is less
386: * than zero or is greater than or equal to the current length.
387: */
388: public StringBuilder deleteCharAt(int index) {
389: deleteCharAt0(index);
390: return this ;
391: }
392:
393: /**
394: * <p>
395: * Inserts the String representation of the <code>boolean</code> value
396: * passed into this object at the <code>offset</code> passed. The
397: * <code>boolean</code> value is converted to a String according to the
398: * rule defined by {@link String#valueOf(boolean)}.
399: * </p>
400: *
401: * @param offset The index of this object to insert the value.
402: * @param b The <code>boolean</code> value to insert into this object.
403: * @return A reference to this object.
404: *
405: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
406: * negative or greater than the current {@link #length()}.
407: *
408: * @see String#valueOf(boolean)
409: */
410: public StringBuilder insert(int offset, boolean b) {
411: insert0(offset, b ? "true" : "false"); //$NON-NLS-1$ //$NON-NLS-2$
412: return this ;
413: }
414:
415: /**
416: * <p>
417: * Inserts the String representation of the <code>char</code> value passed
418: * into this object at the <code>offset</code> passed. The
419: * <code>char</code> value is converted to a String according to the rule
420: * defined by {@link String#valueOf(char)}.
421: * </p>
422: *
423: * @param offset The index of this object to insert the value.
424: * @param c The <code>char</code> value to insert into this object.
425: * @return A reference to this object.
426: *
427: * @throws ArrayIndexOutOfBoundsException if <code>offset</code> is
428: * negative or greater than the current {@link #length()}.
429: *
430: * @see String#valueOf(char)
431: */
432: public StringBuilder insert(int offset, char c) {
433: insert0(offset, c);
434: return this ;
435: }
436:
437: /**
438: * <p>
439: * Inserts the String representation of the <code>int</code> value passed
440: * into this object at the <code>offset</code> passed. The
441: * <code>int</code> value is converted to a String according to the rule
442: * defined by {@link String#valueOf(int)}.
443: * </p>
444: *
445: * @param offset The index of this object to insert the value.
446: * @param i The <code>int</code> value to insert into this object.
447: * @return A reference to this object.
448: *
449: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
450: * negative or greater than the current {@link #length()}.
451: *
452: * @see String#valueOf(int)
453: */
454: public StringBuilder insert(int offset, int i) {
455: insert0(offset, Integer.toString(i));
456: return this ;
457: }
458:
459: /**
460: * <p>
461: * Inserts the String representation of the <code>long</code> value passed
462: * into this object at the <code>offset</code> passed. The
463: * <code>long</code> value is converted to a String according to the rule
464: * defined by {@link String#valueOf(long)}.
465: * </p>
466: *
467: * @param offset The index of this object to insert the value.
468: * @param l The <code>long</code> value to insert into this object.
469: * @return A reference to this object.
470: *
471: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
472: * negative or greater than the current {@link #length()}.
473: *
474: * @see String#valueOf(long)
475: */
476: public StringBuilder insert(int offset, long l) {
477: insert0(offset, Long.toString(l));
478: return this ;
479: }
480:
481: /**
482: * <p>
483: * Inserts the String representation of the <code>float</code> value
484: * passed into this object at the <code>offset</code> passed. The
485: * <code>float</code> value is converted to a String according to the rule
486: * defined by {@link String#valueOf(float)}.
487: * </p>
488: *
489: * @param offset The index of this object to insert the value.
490: * @param f The <code>float</code> value to insert into this object.
491: * @return A reference to this object.
492: *
493: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
494: * negative or greater than the current {@link #length()}.
495: *
496: * @see String#valueOf(float)
497: */
498: public StringBuilder insert(int offset, float f) {
499: insert0(offset, Float.toString(f));
500: return this ;
501: }
502:
503: /**
504: * <p>
505: * Inserts the String representation of the <code>double</code> value
506: * passed into this object at the <code>offset</code> passed. The
507: * <code>double</code> value is converted to a String according to the
508: * rule defined by {@link String#valueOf(double)}.
509: * </p>
510: *
511: * @param offset The index of this object to insert the value.
512: * @param d The <code>double</code> value to insert into this object.
513: * @return A reference to this object.
514: *
515: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
516: * negative or greater than the current {@link #length()}.
517: *
518: * @see String#valueOf(double)
519: */
520: public StringBuilder insert(int offset, double d) {
521: insert0(offset, Double.toString(d));
522: return this ;
523: }
524:
525: /**
526: * <p>
527: * Inserts the String representation of the <code>Object</code> value
528: * passed into this object at the <code>offset</code> passed. The
529: * <code>Object</code> value is converted to a String according to the
530: * rule defined by {@link String#valueOf(Object)}.
531: * </p>
532: *
533: * @param offset The index of this object to insert the value.
534: * @param obj The <code>Object</code> value to insert into this object.
535: * @return A reference to this object.
536: *
537: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
538: * negative or greater than the current {@link #length()}.
539: *
540: * @see String#valueOf(Object)
541: */
542: public StringBuilder insert(int offset, Object obj) {
543: insert0(offset, obj == null ? "null" : obj.toString()); //$NON-NLS-1$
544: return this ;
545: }
546:
547: /**
548: * <p>
549: * Inserts the String value passed into this object at the
550: * <code>offset</code> passed. If the String parameter is null, then the
551: * String <code>"null"</code> is inserted.
552: * </p>
553: *
554: * @param offset The index of this object to insert the value.
555: * @param str The String to insert into this object.
556: * @return A reference to this object.
557: *
558: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
559: * negative or greater than the current {@link #length()}.
560: */
561: public StringBuilder insert(int offset, String str) {
562: insert0(offset, str);
563: return this ;
564: }
565:
566: /**
567: * <p>
568: * Inserts the String representation of the <code>char[]</code> value
569: * passed into this object at the <code>offset</code> passed. The
570: * <code>char[]</code> value is converted to a String according to the
571: * rule defined by {@link String#valueOf(char[])}.
572: * </p>
573: *
574: * @param offset The index of this object to insert the value.
575: * @param ch The <code>char[]</code> value to insert into this object.
576: * @return A reference to this object.
577: *
578: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
579: * negative or greater than the current {@link #length()}.
580: *
581: * @see String#valueOf(char[])
582: */
583: public StringBuilder insert(int offset, char[] ch) {
584: insert0(offset, ch);
585: return this ;
586: }
587:
588: /**
589: * <p>
590: * Inserts the String representation of the subsequence of the
591: * <code>char[]</code> value passed into this object at the
592: * <code>offset</code> passed. The <code>char[]</code> value is
593: * converted to a String according to the rule defined by
594: * {@link String#valueOf(char[],int,int)}.
595: * </p>
596: *
597: * @param offset The index of this object to insert the value.
598: * @param str The <code>char[]</code> value to insert into this object.
599: * @param strOffset The inclusive index of the <code>str</code> parameter
600: * to start copying from.
601: * @param strLen The number of characters to copy from the <code>str</code>
602: * parameter.
603: * @return A reference to this object.
604: *
605: * @throws StringIndexOutOfBoundsException if <code>offset</code> is
606: * negative or greater than the current {@link #length()}.
607: *
608: * @see String#valueOf(char[],int,int)
609: */
610: public StringBuilder insert(int offset, char[] str, int strOffset,
611: int strLen) {
612: insert0(offset, str, strOffset, strLen);
613: return this ;
614: }
615:
616: /**
617: * <p>
618: * Inserts the String representation of the <code>CharSequence</code>
619: * value passed into this object at the <code>offset</code> passed. The
620: * <code>CharSequence</code> value is converted to a String as defined by
621: * {@link CharSequence#toString()}. If the <code>CharSequence</code> is
622: * <code>null</code>, then the String <code>"null"</code> is inserted.
623: * </p>
624: *
625: * @param offset The index of this object to insert the value.
626: * @param s The <code>CharSequence</code> value to insert into this
627: * object.
628: * @return A reference to this object.
629: *
630: * @throws IndexOutOfBoundsException if <code>offset</code> is negative or
631: * greater than the current {@link #length()}.
632: *
633: * @see CharSequence#toString()
634: */
635: public StringBuilder insert(int offset, CharSequence s) {
636: insert0(offset, s == null ? "null" : s.toString()); //$NON-NLS-1$
637: return this ;
638: }
639:
640: /**
641: * <p>
642: * Inserts the String representation of the subsequence of the
643: * <code>CharSequence</code> value passed into this object at the
644: * <code>offset</code> passed. The <code>CharSequence</code> value is
645: * converted to a String as defined by
646: * {@link CharSequence#subSequence(int, int)}. If the
647: * <code>CharSequence</code> is <code>null</code>, then the String
648: * <code>"null"</code> is used to determine the subsequence.
649: * </p>
650: *
651: * @param offset The index of this object to insert the value.
652: * @param s The <code>CharSequence</code> value to insert into this
653: * object.
654: * @param start The start of the subsequence of the <code>s</code>
655: * parameter.
656: * @param end The end of the subsequence of the <code>s</code> parameter.
657: * @return A reference to this object.
658: *
659: * @throws IndexOutOfBoundsException if <code>offset</code> is negative or
660: * greater than the current {@link #length()}.
661: *
662: * @see CharSequence#subSequence(int, int)
663: */
664: public StringBuilder insert(int offset, CharSequence s, int start,
665: int end) {
666: insert0(offset, s, start, end);
667: return this ;
668: }
669:
670: /**
671: * <p>
672: * Replaces the indicated subsequence of this object with the String passed.
673: * If the String passed is longer or shorter than the subsequence, then this
674: * object will be adjusted appropriately.
675: * </p>
676: *
677: * @param start The inclusive start index of the sequence to replace in this
678: * object.
679: * @param end The exclusive end index of the sequence to replace in this
680: * object.
681: * @param str The String to replace the subsequence.
682: * @return A reference to this object.
683: * @throws StringIndexOutOfBoundsException if <code>start</code> is
684: * negative, greater than the current {@link #length()} or greater
685: * than <code>end</code>.
686: * @throws NullPointerException if the <code>str</code> parameter is
687: * <code>null</code>.
688: */
689: public StringBuilder replace(int start, int end, String str) {
690: replace0(start, end, str);
691: return this ;
692: }
693:
694: /**
695: * <p>
696: * Reverses the contents of this object.
697: * </p>
698: *
699: * @return A reference to this object.
700: */
701: public StringBuilder reverse() {
702: reverse0();
703: return this ;
704: }
705:
706: /**
707: * Answers the contents of this StringBuilder.
708: *
709: * @return a String containing the characters in this StringBuilder
710: */
711: @Override
712: public String toString() {
713: /* Note: This method is required to workaround a compiler bug
714: * in the RI javac (at least in 1.5.0_06) that will generate a
715: * reference to the non-public AbstractStringBuilder if we don't
716: * override it here.
717: */
718: return super .toString();
719: }
720:
721: /**
722: * <p>
723: * Reads the state of a <code>StringBuilder</code> from the passed stream
724: * and restores it to this instance.
725: * </p>
726: *
727: * @param in The stream to read the state from.
728: * @throws IOException if the stream throws it during the read.
729: * @throws ClassNotFoundException if the stream throws it during the read.
730: */
731: private void readObject(ObjectInputStream in) throws IOException,
732: ClassNotFoundException {
733: in.defaultReadObject();
734: int count = in.readInt();
735: char[] value = (char[]) in.readObject();
736: set(value, count);
737: }
738:
739: /**
740: * <p>
741: * Writes the state of this object to the stream passed.
742: * </p>
743: *
744: * @param out The stream to write the state to.
745: * @throws IOException if the stream throws it during the write.
746: * @serialData <code>int</code> - The length of this object.
747: * <code>char[]</code> - The buffer from this object, which
748: * may be larger than the length field.
749: */
750: private void writeObject(ObjectOutputStream out) throws IOException {
751: out.defaultWriteObject();
752: out.writeInt(length());
753: out.writeObject(getValue());
754: }
755: }
|