001: /*
002: * Copyright 2003-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package java.lang;
027:
028: /**
029: * A mutable sequence of characters. This class provides an API compatible
030: * with <code>StringBuffer</code>, but with no guarantee of synchronization.
031: * This class is designed for use as a drop-in replacement for
032: * <code>StringBuffer</code> in places where the string buffer was being
033: * used by a single thread (as is generally the case). Where possible,
034: * it is recommended that this class be used in preference to
035: * <code>StringBuffer</code> as it will be faster under most implementations.
036: *
037: * <p>The principal operations on a <code>StringBuilder</code> are the
038: * <code>append</code> and <code>insert</code> methods, which are
039: * overloaded so as to accept data of any type. Each effectively
040: * converts a given datum to a string and then appends or inserts the
041: * characters of that string to the string builder. The
042: * <code>append</code> method always adds these characters at the end
043: * of the builder; the <code>insert</code> method adds the characters at
044: * a specified point.
045: * <p>
046: * For example, if <code>z</code> refers to a string builder object
047: * whose current contents are "<code>start</code>", then
048: * the method call <code>z.append("le")</code> would cause the string
049: * builder to contain "<code>startle</code>", whereas
050: * <code>z.insert(4, "le")</code> would alter the string builder to
051: * contain "<code>starlet</code>".
052: * <p>
053: * In general, if sb refers to an instance of a <code>StringBuilder</code>,
054: * then <code>sb.append(x)</code> has the same effect as
055: * <code>sb.insert(sb.length(), x)</code>.
056: *
057: * Every string builder has a capacity. As long as the length of the
058: * character sequence contained in the string builder does not exceed
059: * the capacity, it is not necessary to allocate a new internal
060: * buffer. If the internal buffer overflows, it is automatically made larger.
061: *
062: * <p>Instances of <code>StringBuilder</code> are not safe for
063: * use by multiple threads. If such synchronization is required then it is
064: * recommended that {@link java.lang.StringBuffer} be used.
065: *
066: * @author Michael McCloskey
067: * @version 1.17, 05/05/07
068: * @see java.lang.StringBuffer
069: * @see java.lang.String
070: * @since 1.5
071: */
072: public final class StringBuilder extends AbstractStringBuilder
073: implements java.io.Serializable, CharSequence {
074:
075: /** use serialVersionUID for interoperability */
076: static final long serialVersionUID = 4383685877147921099L;
077:
078: /**
079: * Constructs a string builder with no characters in it and an
080: * initial capacity of 16 characters.
081: */
082: public StringBuilder() {
083: super (16);
084: }
085:
086: /**
087: * Constructs a string builder with no characters in it and an
088: * initial capacity specified by the <code>capacity</code> argument.
089: *
090: * @param capacity the initial capacity.
091: * @throws NegativeArraySizeException if the <code>capacity</code>
092: * argument is less than <code>0</code>.
093: */
094: public StringBuilder(int capacity) {
095: super (capacity);
096: }
097:
098: /**
099: * Constructs a string builder initialized to the contents of the
100: * specified string. The initial capacity of the string builder is
101: * <code>16</code> plus the length of the string argument.
102: *
103: * @param str the initial contents of the buffer.
104: * @throws NullPointerException if <code>str</code> is <code>null</code>
105: */
106: public StringBuilder(String str) {
107: super (str.length() + 16);
108: append(str);
109: }
110:
111: /**
112: * Constructs a string builder that contains the same characters
113: * as the specified <code>CharSequence</code>. The initial capacity of
114: * the string builder is <code>16</code> plus the length of the
115: * <code>CharSequence</code> argument.
116: *
117: * @param seq the sequence to copy.
118: * @throws NullPointerException if <code>seq</code> is <code>null</code>
119: */
120: public StringBuilder(CharSequence seq) {
121: this (seq.length() + 16);
122: append(seq);
123: }
124:
125: /**
126: * @see java.lang.String#valueOf(java.lang.Object)
127: * @see #append(java.lang.String)
128: */
129: public StringBuilder append(Object obj) {
130: return append(String.valueOf(obj));
131: }
132:
133: public StringBuilder append(String str) {
134: super .append(str);
135: return this ;
136: }
137:
138: // Appends the specified string builder to this sequence.
139: private StringBuilder append(StringBuilder sb) {
140: if (sb == null)
141: return append("null");
142: int len = sb.length();
143: int newcount = count + len;
144: if (newcount > value.length)
145: expandCapacity(newcount);
146: sb.getChars(0, len, value, count);
147: count = newcount;
148: return this ;
149: }
150:
151: /**
152: * Appends the specified <tt>StringBuffer</tt> to this sequence.
153: * <p>
154: * The characters of the <tt>StringBuffer</tt> argument are appended,
155: * in order, to this sequence, increasing the
156: * length of this sequence by the length of the argument.
157: * If <tt>sb</tt> is <tt>null</tt>, then the four characters
158: * <tt>"null"</tt> are appended to this sequence.
159: * <p>
160: * Let <i>n</i> be the length of this character sequence just prior to
161: * execution of the <tt>append</tt> method. Then the character at index
162: * <i>k</i> in the new character sequence is equal to the character at
163: * index <i>k</i> in the old character sequence, if <i>k</i> is less than
164: * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i>
165: * in the argument <code>sb</code>.
166: *
167: * @param sb the <tt>StringBuffer</tt> to append.
168: * @return a reference to this object.
169: */
170: public StringBuilder append(StringBuffer sb) {
171: super .append(sb);
172: return this ;
173: }
174:
175: /**
176: * @throws IndexOutOfBoundsException {@inheritDoc}
177: */
178: public StringBuilder append(CharSequence s) {
179: if (s == null)
180: s = "null";
181: if (s instanceof String)
182: return this .append((String) s);
183: if (s instanceof StringBuffer)
184: return this .append((StringBuffer) s);
185: if (s instanceof StringBuilder)
186: return this .append((StringBuilder) s);
187: return this .append(s, 0, s.length());
188: }
189:
190: /**
191: * @throws IndexOutOfBoundsException {@inheritDoc}
192: */
193: public StringBuilder append(CharSequence s, int start, int end) {
194: super .append(s, start, end);
195: return this ;
196: }
197:
198: public StringBuilder append(char str[]) {
199: super .append(str);
200: return this ;
201: }
202:
203: public StringBuilder append(char str[], int offset, int len) {
204: super .append(str, offset, len);
205: return this ;
206: }
207:
208: /**
209: * @see java.lang.String#valueOf(boolean)
210: * @see #append(java.lang.String)
211: */
212: public StringBuilder append(boolean b) {
213: super .append(b);
214: return this ;
215: }
216:
217: public StringBuilder append(char c) {
218: super .append(c);
219: return this ;
220: }
221:
222: /**
223: * @see java.lang.String#valueOf(int)
224: * @see #append(java.lang.String)
225: */
226: public StringBuilder append(int i) {
227: super .append(i);
228: return this ;
229: }
230:
231: /**
232: * @see java.lang.String#valueOf(long)
233: * @see #append(java.lang.String)
234: */
235: public StringBuilder append(long lng) {
236: super .append(lng);
237: return this ;
238: }
239:
240: /**
241: * @see java.lang.String#valueOf(float)
242: * @see #append(java.lang.String)
243: */
244: public StringBuilder append(float f) {
245: super .append(f);
246: return this ;
247: }
248:
249: /**
250: * @see java.lang.String#valueOf(double)
251: * @see #append(java.lang.String)
252: */
253: public StringBuilder append(double d) {
254: super .append(d);
255: return this ;
256: }
257:
258: /**
259: * @since 1.5
260: */
261: public StringBuilder appendCodePoint(int codePoint) {
262: super .appendCodePoint(codePoint);
263: return this ;
264: }
265:
266: /**
267: * @throws StringIndexOutOfBoundsException {@inheritDoc}
268: */
269: public StringBuilder delete(int start, int end) {
270: super .delete(start, end);
271: return this ;
272: }
273:
274: /**
275: * @throws StringIndexOutOfBoundsException {@inheritDoc}
276: */
277: public StringBuilder deleteCharAt(int index) {
278: super .deleteCharAt(index);
279: return this ;
280: }
281:
282: /**
283: * @throws StringIndexOutOfBoundsException {@inheritDoc}
284: */
285: public StringBuilder replace(int start, int end, String str) {
286: super .replace(start, end, str);
287: return this ;
288: }
289:
290: /**
291: * @throws StringIndexOutOfBoundsException {@inheritDoc}
292: */
293: public StringBuilder insert(int index, char str[], int offset,
294: int len) {
295: super .insert(index, str, offset, len);
296: return this ;
297: }
298:
299: /**
300: * @throws StringIndexOutOfBoundsException {@inheritDoc}
301: * @see java.lang.String#valueOf(java.lang.Object)
302: * @see #insert(int, java.lang.String)
303: * @see #length()
304: */
305: public StringBuilder insert(int offset, Object obj) {
306: return insert(offset, String.valueOf(obj));
307: }
308:
309: /**
310: * @throws StringIndexOutOfBoundsException {@inheritDoc}
311: * @see #length()
312: */
313: public StringBuilder insert(int offset, String str) {
314: super .insert(offset, str);
315: return this ;
316: }
317:
318: /**
319: * @throws StringIndexOutOfBoundsException {@inheritDoc}
320: */
321: public StringBuilder insert(int offset, char str[]) {
322: super .insert(offset, str);
323: return this ;
324: }
325:
326: /**
327: * @throws IndexOutOfBoundsException {@inheritDoc}
328: */
329: public StringBuilder insert(int dstOffset, CharSequence s) {
330: if (s == null)
331: s = "null";
332: if (s instanceof String)
333: return this .insert(dstOffset, (String) s);
334: return this .insert(dstOffset, s, 0, s.length());
335: }
336:
337: /**
338: * @throws IndexOutOfBoundsException {@inheritDoc}
339: */
340: public StringBuilder insert(int dstOffset, CharSequence s,
341: int start, int end) {
342: super .insert(dstOffset, s, start, end);
343: return this ;
344: }
345:
346: /**
347: * @throws StringIndexOutOfBoundsException {@inheritDoc}
348: * @see java.lang.String#valueOf(boolean)
349: * @see #insert(int, java.lang.String)
350: * @see #length()
351: */
352: public StringBuilder insert(int offset, boolean b) {
353: super .insert(offset, b);
354: return this ;
355: }
356:
357: /**
358: * @throws IndexOutOfBoundsException {@inheritDoc}
359: * @see #length()
360: */
361: public StringBuilder insert(int offset, char c) {
362: super .insert(offset, c);
363: return this ;
364: }
365:
366: /**
367: * @throws StringIndexOutOfBoundsException {@inheritDoc}
368: * @see java.lang.String#valueOf(int)
369: * @see #insert(int, java.lang.String)
370: * @see #length()
371: */
372: public StringBuilder insert(int offset, int i) {
373: return insert(offset, String.valueOf(i));
374: }
375:
376: /**
377: * @throws StringIndexOutOfBoundsException {@inheritDoc}
378: * @see java.lang.String#valueOf(long)
379: * @see #insert(int, java.lang.String)
380: * @see #length()
381: */
382: public StringBuilder insert(int offset, long l) {
383: return insert(offset, String.valueOf(l));
384: }
385:
386: /**
387: * @throws StringIndexOutOfBoundsException {@inheritDoc}
388: * @see java.lang.String#valueOf(float)
389: * @see #insert(int, java.lang.String)
390: * @see #length()
391: */
392: public StringBuilder insert(int offset, float f) {
393: return insert(offset, String.valueOf(f));
394: }
395:
396: /**
397: * @throws StringIndexOutOfBoundsException {@inheritDoc}
398: * @see java.lang.String#valueOf(double)
399: * @see #insert(int, java.lang.String)
400: * @see #length()
401: */
402: public StringBuilder insert(int offset, double d) {
403: return insert(offset, String.valueOf(d));
404: }
405:
406: /**
407: * @throws NullPointerException {@inheritDoc}
408: */
409: public int indexOf(String str) {
410: return indexOf(str, 0);
411: }
412:
413: /**
414: * @throws NullPointerException {@inheritDoc}
415: */
416: public int indexOf(String str, int fromIndex) {
417: return String.indexOf(value, 0, count, str.toCharArray(), 0,
418: str.length(), fromIndex);
419: }
420:
421: /**
422: * @throws NullPointerException {@inheritDoc}
423: */
424: public int lastIndexOf(String str) {
425: return lastIndexOf(str, count);
426: }
427:
428: /**
429: * @throws NullPointerException {@inheritDoc}
430: */
431: public int lastIndexOf(String str, int fromIndex) {
432: return String.lastIndexOf(value, 0, count, str.toCharArray(),
433: 0, str.length(), fromIndex);
434: }
435:
436: public StringBuilder reverse() {
437: super .reverse();
438: return this ;
439: }
440:
441: public String toString() {
442: // Create a copy, don't share the array
443: return new String(value, 0, count);
444: }
445:
446: /**
447: * Save the state of the <tt>StringBuilder</tt> instance to a stream
448: * (that is, serialize it).
449: *
450: * @serialData the number of characters currently stored in the string
451: * builder (<tt>int</tt>), followed by the characters in the
452: * string builder (<tt>char[]</tt>). The length of the
453: * <tt>char</tt> array may be greater than the number of
454: * characters currently stored in the string builder, in which
455: * case extra characters are ignored.
456: */
457: private void writeObject(java.io.ObjectOutputStream s)
458: throws java.io.IOException {
459: s.defaultWriteObject();
460: s.writeInt(count);
461: s.writeObject(value);
462: }
463:
464: /**
465: * readObject is called to restore the state of the StringBuffer from
466: * a stream.
467: */
468: private void readObject(java.io.ObjectInputStream s)
469: throws java.io.IOException, ClassNotFoundException {
470: s.defaultReadObject();
471: count = s.readInt();
472: value = (char[]) s.readObject();
473: }
474:
475: }
|