1 /* StringBuffer.java -- Growable strings
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
41 import java
.io
.Serializable
;
44 * <code>StringBuffer</code> represents a changeable <code>String</code>.
45 * It provides the operations required to modify the
46 * <code>StringBuffer</code>, including insert, replace, delete, append,
47 * and reverse. It is thread-safe; meaning that all modifications to a buffer
48 * are in synchronized methods.
50 * <p><code>StringBuffer</code>s are variable-length in nature, so even if
51 * you initialize them to a certain size, they can still grow larger than
52 * that. <em>Capacity</em> indicates the number of characters the
53 * <code>StringBuffer</code> can have in it before it has to grow (growing
54 * the char array is an expensive operation involving <code>new</code>).
56 * <p>Incidentally, compilers often implement the String operator "+"
57 * by using a <code>StringBuffer</code> operation:<br>
58 * <code>a + b</code><br>
60 * <code>new StringBuffer().append(a).append(b).toString()</code>.
62 * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
63 * efficiency. This will help when a StringBuffer is converted to a String
64 * and the StringBuffer is not changed after that (quite common when performing
65 * string concatenation).
70 * @author Eric Blake (ebb9@email.byu.edu)
73 * @status updated to 1.4
75 public final class StringBuffer
implements Serializable
, CharSequence
78 * Compatible with JDK 1.0+.
80 private static final long serialVersionUID
= 3388685877147921107L;
83 * Index of next available character (and thus the size of the current
84 * string contents). Note that this has permissions set this way so that
85 * String can get the value.
87 * @serial the number of characters in the buffer
92 * The buffer. Note that this has permissions set this way so that String
100 * True if the buffer is shared with another object (StringBuffer or
101 * String); this means the buffer must be copied before writing to it again.
102 * Note that this has permissions set this way so that String can get the
105 * @serial whether the buffer is shared
110 * The default capacity of a buffer.
112 private static final int DEFAULT_CAPACITY
= 16;
115 * Create a new StringBuffer with default capacity 16.
117 public StringBuffer()
119 this(DEFAULT_CAPACITY
);
123 * Create an empty <code>StringBuffer</code> with the specified initial
126 * @param capacity the initial capacity
127 * @throws NegativeArraySizeException if capacity is negative
129 public StringBuffer(int capacity
)
131 value
= new char[capacity
];
135 * Create a new <code>StringBuffer</code> with the characters in the
136 * specified <code>String</code>. Initial capacity will be the size of the
139 * @param str the <code>String</code> to convert
140 * @throws NullPointerException if str is null
142 public StringBuffer(String str
)
144 // Unfortunately, because the size is 16 larger, we cannot share.
146 value
= new char[count
+ DEFAULT_CAPACITY
];
147 str
.getChars(0, count
, value
, 0);
151 * Create a new <code>StringBuffer</code> with the characters from the
152 * specified <code>CharSequence</code>. Initial capacity will be the
153 * size of the CharSequence plus 16.
155 * @param sequence the <code>String</code> to convert
156 * @throws NullPointerException if str is null
160 public StringBuffer(CharSequence sequence
)
162 count
= Math
.max(0, sequence
.length());
163 value
= new char[count
+ DEFAULT_CAPACITY
];
164 for (int i
= 0; i
< count
; ++i
)
165 value
[i
] = sequence
.charAt(i
);
169 * Get the length of the <code>String</code> this <code>StringBuffer</code>
170 * would create. Not to be confused with the <em>capacity</em> of the
171 * <code>StringBuffer</code>.
173 * @return the length of this <code>StringBuffer</code>
175 * @see #setLength(int)
177 public synchronized int length()
183 * Get the total number of characters this <code>StringBuffer</code> can
184 * support before it must be grown. Not to be confused with <em>length</em>.
186 * @return the capacity of this <code>StringBuffer</code>
188 * @see #ensureCapacity(int)
190 public synchronized int capacity()
196 * Increase the capacity of this <code>StringBuffer</code>. This will
197 * ensure that an expensive growing operation will not occur until
198 * <code>minimumCapacity</code> is reached. The buffer is grown to the
199 * larger of <code>minimumCapacity</code> and
200 * <code>capacity() * 2 + 2</code>, if it is not already large enough.
202 * @param minimumCapacity the new capacity
205 public synchronized void ensureCapacity(int minimumCapacity
)
207 ensureCapacity_unsynchronized(minimumCapacity
);
211 * Set the length of this StringBuffer. If the new length is greater than
212 * the current length, all the new characters are set to '\0'. If the new
213 * length is less than the current length, the first <code>newLength</code>
214 * characters of the old array will be preserved, and the remaining
215 * characters are truncated.
217 * @param newLength the new length
218 * @throws IndexOutOfBoundsException if the new length is negative
219 * (while unspecified, this is a StringIndexOutOfBoundsException)
222 public synchronized void setLength(int newLength
)
225 throw new StringIndexOutOfBoundsException(newLength
);
227 int valueLength
= value
.length
;
229 /* Always call ensureCapacity_unsynchronized in order to preserve
230 copy-on-write semantics. */
231 ensureCapacity_unsynchronized(newLength
);
233 if (newLength
< valueLength
)
235 /* If the StringBuffer's value just grew, then we know that
236 value is newly allocated and the region between count and
237 newLength is filled with '\0'. */
242 /* The StringBuffer's value doesn't need to grow. However,
243 we should clear out any cruft that may exist. */
244 while (count
< newLength
)
245 value
[count
++] = '\0';
250 * Get the character at the specified index.
252 * @param index the index of the character to get, starting at 0
253 * @return the character at the specified index
254 * @throws IndexOutOfBoundsException if index is negative or >= length()
256 public synchronized char charAt(int index
)
258 if (index
< 0 || index
>= count
)
259 throw new StringIndexOutOfBoundsException(index
);
264 * Get the code point at the specified index. This is like #charAt(int),
265 * but if the character is the start of a surrogate pair, and the
266 * following character completes the pair, then the corresponding
267 * supplementary code point is returned.
268 * @param index the index of the codepoint to get, starting at 0
269 * @return the codepoint at the specified index
270 * @throws IndexOutOfBoundsException if index is negative or >= length()
273 public synchronized int codePointAt(int index
)
275 return Character
.codePointAt(value
, index
, count
);
279 * Get the code point before the specified index. This is like
280 * #codePointAt(int), but checks the characters at <code>index-1</code> and
281 * <code>index-2</code> to see if they form a supplementary code point.
282 * @param index the index just past the codepoint to get, starting at 0
283 * @return the codepoint at the specified index
284 * @throws IndexOutOfBoundsException if index is negative or >= length()
287 public synchronized int codePointBefore(int index
)
289 // Character.codePointBefore() doesn't perform this check. We
290 // could use the CharSequence overload, but this is just as easy.
292 throw new IndexOutOfBoundsException();
293 return Character
.codePointBefore(value
, index
, 1);
297 * Get the specified array of characters. <code>srcOffset - srcEnd</code>
298 * characters will be copied into the array you pass in.
300 * @param srcOffset the index to start copying from (inclusive)
301 * @param srcEnd the index to stop copying from (exclusive)
302 * @param dst the array to copy into
303 * @param dstOffset the index to start copying into
304 * @throws NullPointerException if dst is null
305 * @throws IndexOutOfBoundsException if any source or target indices are
306 * out of range (while unspecified, source problems cause a
307 * StringIndexOutOfBoundsException, and dest problems cause an
308 * ArrayIndexOutOfBoundsException)
309 * @see System#arraycopy(Object, int, Object, int, int)
311 public synchronized void getChars(int srcOffset
, int srcEnd
,
312 char[] dst
, int dstOffset
)
314 if (srcOffset
< 0 || srcEnd
> count
|| srcEnd
< srcOffset
)
315 throw new StringIndexOutOfBoundsException();
316 VMSystem
.arraycopy(value
, srcOffset
, dst
, dstOffset
, srcEnd
- srcOffset
);
320 * Set the character at the specified index.
322 * @param index the index of the character to set starting at 0
323 * @param ch the value to set that character to
324 * @throws IndexOutOfBoundsException if index is negative or >= length()
325 * (while unspecified, this is a StringIndexOutOfBoundsException)
327 public synchronized void setCharAt(int index
, char ch
)
329 if (index
< 0 || index
>= count
)
330 throw new StringIndexOutOfBoundsException(index
);
331 // Call ensureCapacity to enforce copy-on-write.
332 ensureCapacity_unsynchronized(count
);
337 * Append the <code>String</code> value of the argument to this
338 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
339 * to <code>String</code>.
341 * @param obj the <code>Object</code> to convert and append
342 * @return this <code>StringBuffer</code>
343 * @see String#valueOf(Object)
344 * @see #append(String)
346 public StringBuffer
append(Object obj
)
348 return append(obj
== null ?
"null" : obj
.toString());
352 * Append the <code>String</code> to this <code>StringBuffer</code>. If
353 * str is null, the String "null" is appended.
355 * @param str the <code>String</code> to append
356 * @return this <code>StringBuffer</code>
358 public synchronized StringBuffer
append(String str
)
363 ensureCapacity_unsynchronized(count
+ len
);
364 str
.getChars(0, len
, value
, count
);
370 * Append the <code>StringBuffer</code> value of the argument to this
371 * <code>StringBuffer</code>. This behaves the same as
372 * <code>append((Object) stringBuffer)</code>, except it is more efficient.
374 * @param stringBuffer the <code>StringBuffer</code> to convert and append
375 * @return this <code>StringBuffer</code>
376 * @see #append(Object)
379 public synchronized StringBuffer
append(StringBuffer stringBuffer
)
381 if (stringBuffer
== null)
382 return append("null");
383 synchronized (stringBuffer
)
385 int len
= stringBuffer
.count
;
386 ensureCapacity_unsynchronized(count
+ len
);
387 VMSystem
.arraycopy(stringBuffer
.value
, 0, value
, count
, len
);
394 * Append the <code>CharSequence</code> value of the argument to this
395 * <code>StringBuffer</code>.
397 * @param sequence the <code>CharSequence</code> to append
398 * @return this <code>StringBuffer</code>
399 * @see #append(Object)
402 public synchronized StringBuffer
append(CharSequence sequence
)
404 if (sequence
== null)
406 return append(sequence
, 0, sequence
.length());
410 * Append the specified subsequence of the <code>CharSequence</code>
411 * argument to this <code>StringBuffer</code>.
413 * @param sequence the <code>CharSequence</code> to append
414 * @param start the starting index
415 * @param end one past the ending index
416 * @return this <code>StringBuffer</code>
417 * @see #append(Object)
420 public synchronized StringBuffer
append(CharSequence sequence
,
423 if (sequence
== null)
425 if (start
< 0 || end
< 0 || start
> end
|| end
> sequence
.length())
426 throw new IndexOutOfBoundsException();
427 ensureCapacity_unsynchronized(this.count
+ end
- start
);
428 for (int i
= start
; i
< end
; ++i
)
429 value
[count
++] = sequence
.charAt(i
);
434 * Append the <code>char</code> array to this <code>StringBuffer</code>.
435 * This is similar (but more efficient) than
436 * <code>append(new String(data))</code>, except in the case of null.
438 * @param data the <code>char[]</code> to append
439 * @return this <code>StringBuffer</code>
440 * @throws NullPointerException if <code>str</code> is <code>null</code>
441 * @see #append(char[], int, int)
443 public StringBuffer
append(char[] data
)
445 return append(data
, 0, data
.length
);
449 * Append part of the <code>char</code> array to this
450 * <code>StringBuffer</code>. This is similar (but more efficient) than
451 * <code>append(new String(data, offset, count))</code>, except in the case
454 * @param data the <code>char[]</code> to append
455 * @param offset the start location in <code>str</code>
456 * @param count the number of characters to get from <code>str</code>
457 * @return this <code>StringBuffer</code>
458 * @throws NullPointerException if <code>str</code> is <code>null</code>
459 * @throws IndexOutOfBoundsException if offset or count is out of range
460 * (while unspecified, this is a StringIndexOutOfBoundsException)
462 public synchronized StringBuffer
append(char[] data
, int offset
, int count
)
464 if (offset
< 0 || count
< 0 || offset
> data
.length
- count
)
465 throw new StringIndexOutOfBoundsException();
466 ensureCapacity_unsynchronized(this.count
+ count
);
467 VMSystem
.arraycopy(data
, offset
, value
, this.count
, count
);
473 * Append the <code>String</code> value of the argument to this
474 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
475 * to <code>String</code>.
477 * @param bool the <code>boolean</code> to convert and append
478 * @return this <code>StringBuffer</code>
479 * @see String#valueOf(boolean)
481 public StringBuffer
append(boolean bool
)
483 return append(bool ?
"true" : "false");
487 * Append the <code>char</code> to this <code>StringBuffer</code>.
489 * @param ch the <code>char</code> to append
490 * @return this <code>StringBuffer</code>
492 public synchronized StringBuffer
append(char ch
)
494 ensureCapacity_unsynchronized(count
+ 1);
500 * Append the code point to this <code>StringBuffer</code>.
501 * This is like #append(char), but will append two characters
502 * if a supplementary code point is given.
504 * @param code the code point to append
505 * @return this <code>StringBuffer</code>
506 * @see Character#toChars(int, char[], int)
509 public synchronized StringBuffer
appendCodePoint(int code
)
511 int len
= Character
.charCount(code
);
512 ensureCapacity_unsynchronized(count
+ len
);
513 Character
.toChars(code
, value
, count
);
519 * Append the <code>String</code> value of the argument to this
520 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
521 * to <code>String</code>.
523 * @param inum the <code>int</code> to convert and append
524 * @return this <code>StringBuffer</code>
525 * @see String#valueOf(int)
527 // This is native in libgcj, for efficiency.
528 public StringBuffer
append(int inum
)
530 return append(String
.valueOf(inum
));
534 * Append the <code>String</code> value of the argument to this
535 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
536 * to <code>String</code>.
538 * @param lnum the <code>long</code> to convert and append
539 * @return this <code>StringBuffer</code>
540 * @see String#valueOf(long)
542 public StringBuffer
append(long lnum
)
544 return append(Long
.toString(lnum
, 10));
548 * Append the <code>String</code> value of the argument to this
549 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
550 * to <code>String</code>.
552 * @param fnum the <code>float</code> to convert and append
553 * @return this <code>StringBuffer</code>
554 * @see String#valueOf(float)
556 public StringBuffer
append(float fnum
)
558 return append(Float
.toString(fnum
));
562 * Append the <code>String</code> value of the argument to this
563 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
564 * to <code>String</code>.
566 * @param dnum the <code>double</code> to convert and append
567 * @return this <code>StringBuffer</code>
568 * @see String#valueOf(double)
570 public StringBuffer
append(double dnum
)
572 return append(Double
.toString(dnum
));
576 * Delete characters from this <code>StringBuffer</code>.
577 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
578 * harmless for end to be larger than length().
580 * @param start the first character to delete
581 * @param end the index after the last character to delete
582 * @return this <code>StringBuffer</code>
583 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
586 public synchronized StringBuffer
delete(int start
, int end
)
588 if (start
< 0 || start
> count
|| start
> end
)
589 throw new StringIndexOutOfBoundsException(start
);
592 // This will unshare if required.
593 ensureCapacity_unsynchronized(count
);
594 if (count
- end
!= 0)
595 VMSystem
.arraycopy(value
, end
, value
, start
, count
- end
);
596 count
-= end
- start
;
601 * Delete a character from this <code>StringBuffer</code>.
603 * @param index the index of the character to delete
604 * @return this <code>StringBuffer</code>
605 * @throws StringIndexOutOfBoundsException if index is out of bounds
608 public StringBuffer
deleteCharAt(int index
)
610 return delete(index
, index
+ 1);
614 * Replace characters between index <code>start</code> (inclusive) and
615 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
616 * is larger than the size of this StringBuffer, all characters after
617 * <code>start</code> are replaced.
619 * @param start the beginning index of characters to delete (inclusive)
620 * @param end the ending index of characters to delete (exclusive)
621 * @param str the new <code>String</code> to insert
622 * @return this <code>StringBuffer</code>
623 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
624 * @throws NullPointerException if str is null
627 public synchronized StringBuffer
replace(int start
, int end
, String str
)
629 if (start
< 0 || start
> count
|| start
> end
)
630 throw new StringIndexOutOfBoundsException(start
);
633 // Calculate the difference in 'count' after the replace.
634 int delta
= len
- (end
> count ? count
: end
) + start
;
635 ensureCapacity_unsynchronized(count
+ delta
);
637 if (delta
!= 0 && end
< count
)
638 VMSystem
.arraycopy(value
, end
, value
, end
+ delta
, count
- end
);
640 str
.getChars(0, len
, value
, start
);
646 * Creates a substring of this StringBuffer, starting at a specified index
647 * and ending at the end of this StringBuffer.
649 * @param beginIndex index to start substring (base 0)
650 * @return new String which is a substring of this StringBuffer
651 * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
652 * @see #substring(int, int)
655 public String
substring(int beginIndex
)
657 return substring(beginIndex
, count
);
661 * Creates a substring of this StringBuffer, starting at a specified index
662 * and ending at one character before a specified index. This is implemented
663 * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
664 * the CharSequence interface.
666 * @param beginIndex index to start at (inclusive, base 0)
667 * @param endIndex index to end at (exclusive)
668 * @return new String which is a substring of this StringBuffer
669 * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
671 * @see #substring(int, int)
674 public CharSequence
subSequence(int beginIndex
, int endIndex
)
676 return substring(beginIndex
, endIndex
);
680 * Creates a substring of this StringBuffer, starting at a specified index
681 * and ending at one character before a specified index.
683 * @param beginIndex index to start at (inclusive, base 0)
684 * @param endIndex index to end at (exclusive)
685 * @return new String which is a substring of this StringBuffer
686 * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
690 public synchronized String
substring(int beginIndex
, int endIndex
)
692 int len
= endIndex
- beginIndex
;
693 if (beginIndex
< 0 || endIndex
> count
|| endIndex
< beginIndex
)
694 throw new StringIndexOutOfBoundsException();
697 // Don't copy unless substring is smaller than 1/4 of the buffer.
698 boolean share_buffer
= ((len
<< 2) >= value
.length
);
701 // Package constructor avoids an array copy.
702 return new String(value
, beginIndex
, len
, share_buffer
);
706 * Insert a subarray of the <code>char[]</code> argument into this
707 * <code>StringBuffer</code>.
709 * @param offset the place to insert in this buffer
710 * @param str the <code>char[]</code> to insert
711 * @param str_offset the index in <code>str</code> to start inserting from
712 * @param len the number of characters to insert
713 * @return this <code>StringBuffer</code>
714 * @throws NullPointerException if <code>str</code> is <code>null</code>
715 * @throws StringIndexOutOfBoundsException if any index is out of bounds
718 public synchronized StringBuffer
insert(int offset
,
719 char[] str
, int str_offset
, int len
)
721 if (offset
< 0 || offset
> count
|| len
< 0
722 || str_offset
< 0 || str_offset
> str
.length
- len
)
723 throw new StringIndexOutOfBoundsException();
724 ensureCapacity_unsynchronized(count
+ len
);
725 VMSystem
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
726 VMSystem
.arraycopy(str
, str_offset
, value
, offset
, len
);
732 * Insert the <code>String</code> value of the argument into this
733 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
734 * to <code>String</code>.
736 * @param offset the place to insert in this buffer
737 * @param obj the <code>Object</code> to convert and insert
738 * @return this <code>StringBuffer</code>
739 * @exception StringIndexOutOfBoundsException if offset is out of bounds
740 * @see String#valueOf(Object)
742 public StringBuffer
insert(int offset
, Object obj
)
744 return insert(offset
, obj
== null ?
"null" : obj
.toString());
748 * Insert the <code>String</code> argument into this
749 * <code>StringBuffer</code>. If str is null, the String "null" is used
752 * @param offset the place to insert in this buffer
753 * @param str the <code>String</code> to insert
754 * @return this <code>StringBuffer</code>
755 * @throws StringIndexOutOfBoundsException if offset is out of bounds
757 public synchronized StringBuffer
insert(int offset
, String str
)
759 if (offset
< 0 || offset
> count
)
760 throw new StringIndexOutOfBoundsException(offset
);
764 ensureCapacity_unsynchronized(count
+ len
);
765 VMSystem
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
766 str
.getChars(0, len
, value
, offset
);
772 * Insert the <code>CharSequence</code> argument into this
773 * <code>StringBuffer</code>. If the sequence is null, the String
774 * "null" is used instead.
776 * @param offset the place to insert in this buffer
777 * @param sequence the <code>CharSequence</code> to insert
778 * @return this <code>StringBuffer</code>
779 * @throws IndexOutOfBoundsException if offset is out of bounds
782 public synchronized StringBuffer
insert(int offset
, CharSequence sequence
)
784 if (sequence
== null)
786 return insert(offset
, sequence
, 0, sequence
.length());
790 * Insert a subsequence of the <code>CharSequence</code> argument into this
791 * <code>StringBuffer</code>. If the sequence is null, the String
792 * "null" is used instead.
794 * @param offset the place to insert in this buffer
795 * @param sequence the <code>CharSequence</code> to insert
796 * @param start the starting index of the subsequence
797 * @param end one past the ending index of the subsequence
798 * @return this <code>StringBuffer</code>
799 * @throws IndexOutOfBoundsException if offset, start,
800 * or end are out of bounds
803 public synchronized StringBuffer
insert(int offset
, CharSequence sequence
,
806 if (sequence
== null)
808 if (start
< 0 || end
< 0 || start
> end
|| end
> sequence
.length())
809 throw new IndexOutOfBoundsException();
810 int len
= end
- start
;
811 ensureCapacity_unsynchronized(count
+ len
);
812 VMSystem
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
813 for (int i
= start
; i
< end
; ++i
)
814 value
[offset
++] = sequence
.charAt(i
);
820 * Insert the <code>char[]</code> argument into this
821 * <code>StringBuffer</code>.
823 * @param offset the place to insert in this buffer
824 * @param data the <code>char[]</code> to insert
825 * @return this <code>StringBuffer</code>
826 * @throws NullPointerException if <code>data</code> is <code>null</code>
827 * @throws StringIndexOutOfBoundsException if offset is out of bounds
828 * @see #insert(int, char[], int, int)
830 public StringBuffer
insert(int offset
, char[] data
)
832 return insert(offset
, data
, 0, data
.length
);
836 * Insert the <code>String</code> value of the argument into this
837 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
838 * to <code>String</code>.
840 * @param offset the place to insert in this buffer
841 * @param bool the <code>boolean</code> to convert and insert
842 * @return this <code>StringBuffer</code>
843 * @throws StringIndexOutOfBoundsException if offset is out of bounds
844 * @see String#valueOf(boolean)
846 public StringBuffer
insert(int offset
, boolean bool
)
848 return insert(offset
, bool ?
"true" : "false");
852 * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
854 * @param offset the place to insert in this buffer
855 * @param ch the <code>char</code> to insert
856 * @return this <code>StringBuffer</code>
857 * @throws StringIndexOutOfBoundsException if offset is out of bounds
859 public synchronized StringBuffer
insert(int offset
, char ch
)
861 if (offset
< 0 || offset
> count
)
862 throw new StringIndexOutOfBoundsException(offset
);
863 ensureCapacity_unsynchronized(count
+ 1);
864 VMSystem
.arraycopy(value
, offset
, value
, offset
+ 1, count
- offset
);
871 * Insert the <code>String</code> value of the argument into this
872 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
873 * to <code>String</code>.
875 * @param offset the place to insert in this buffer
876 * @param inum the <code>int</code> to convert and insert
877 * @return this <code>StringBuffer</code>
878 * @throws StringIndexOutOfBoundsException if offset is out of bounds
879 * @see String#valueOf(int)
881 public StringBuffer
insert(int offset
, int inum
)
883 return insert(offset
, String
.valueOf(inum
));
887 * Insert the <code>String</code> value of the argument into this
888 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
889 * to <code>String</code>.
891 * @param offset the place to insert in this buffer
892 * @param lnum the <code>long</code> to convert and insert
893 * @return this <code>StringBuffer</code>
894 * @throws StringIndexOutOfBoundsException if offset is out of bounds
895 * @see String#valueOf(long)
897 public StringBuffer
insert(int offset
, long lnum
)
899 return insert(offset
, Long
.toString(lnum
, 10));
903 * Insert the <code>String</code> value of the argument into this
904 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
905 * to <code>String</code>.
907 * @param offset the place to insert in this buffer
908 * @param fnum the <code>float</code> to convert and insert
909 * @return this <code>StringBuffer</code>
910 * @throws StringIndexOutOfBoundsException if offset is out of bounds
911 * @see String#valueOf(float)
913 public StringBuffer
insert(int offset
, float fnum
)
915 return insert(offset
, Float
.toString(fnum
));
919 * Insert the <code>String</code> value of the argument into this
920 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
921 * to <code>String</code>.
923 * @param offset the place to insert in this buffer
924 * @param dnum the <code>double</code> to convert and insert
925 * @return this <code>StringBuffer</code>
926 * @throws StringIndexOutOfBoundsException if offset is out of bounds
927 * @see String#valueOf(double)
929 public StringBuffer
insert(int offset
, double dnum
)
931 return insert(offset
, Double
.toString(dnum
));
935 * Finds the first instance of a substring in this StringBuffer.
937 * @param str String to find
938 * @return location (base 0) of the String, or -1 if not found
939 * @throws NullPointerException if str is null
940 * @see #indexOf(String, int)
943 public int indexOf(String str
)
945 return indexOf(str
, 0);
949 * Finds the first instance of a String in this StringBuffer, starting at
950 * a given index. If starting index is less than 0, the search starts at
951 * the beginning of this String. If the starting index is greater than the
952 * length of this String, or the substring is not found, -1 is returned.
954 * @param str String to find
955 * @param fromIndex index to start the search
956 * @return location (base 0) of the String, or -1 if not found
957 * @throws NullPointerException if str is null
960 public synchronized int indexOf(String str
, int fromIndex
)
964 int limit
= count
- str
.count
;
965 for ( ; fromIndex
<= limit
; fromIndex
++)
966 if (regionMatches(fromIndex
, str
))
972 * Finds the last instance of a substring in this StringBuffer.
974 * @param str String to find
975 * @return location (base 0) of the String, or -1 if not found
976 * @throws NullPointerException if str is null
977 * @see #lastIndexOf(String, int)
980 public int lastIndexOf(String str
)
982 return lastIndexOf(str
, count
- str
.count
);
986 * Finds the last instance of a String in this StringBuffer, starting at a
987 * given index. If starting index is greater than the maximum valid index,
988 * then the search begins at the end of this String. If the starting index
989 * is less than zero, or the substring is not found, -1 is returned.
991 * @param str String to find
992 * @param fromIndex index to start the search
993 * @return location (base 0) of the String, or -1 if not found
994 * @throws NullPointerException if str is null
997 public synchronized int lastIndexOf(String str
, int fromIndex
)
999 fromIndex
= Math
.min(fromIndex
, count
- str
.count
);
1000 for ( ; fromIndex
>= 0; fromIndex
--)
1001 if (regionMatches(fromIndex
, str
))
1007 * Reverse the characters in this StringBuffer. The same sequence of
1008 * characters exists, but in the reverse index ordering.
1010 * @return this <code>StringBuffer</code>
1012 public synchronized StringBuffer
reverse()
1014 // Call ensureCapacity to enforce copy-on-write.
1015 ensureCapacity_unsynchronized(count
);
1016 for (int i
= count
>> 1, j
= count
- i
; --i
>= 0; ++j
)
1019 value
[i
] = value
[j
];
1026 * Convert this <code>StringBuffer</code> to a <code>String</code>. The
1027 * String is composed of the characters currently in this StringBuffer. Note
1028 * that the result is a copy, and that future modifications to this buffer
1029 * do not affect the String.
1031 * @return the characters in this StringBuffer
1033 public String
toString()
1035 // The string will set this.shared = true.
1036 return new String(this);
1040 * This may reduce the amount of memory used by the StringBuffer,
1041 * by resizing the internal array to remove unused space. However,
1042 * this method is not required to resize, so this behavior cannot
1046 public synchronized void trimToSize()
1048 int wouldSave
= value
.length
- count
;
1049 // Some random heuristics: if we save less than 20 characters, who
1053 // If we save more than 200 characters, shrink.
1054 // If we save more than 1/4 of the buffer, shrink.
1055 if (wouldSave
> 200 || wouldSave
* 4 > value
.length
)
1057 char[] newValue
= new char[count
];
1058 VMSystem
.arraycopy(value
, 0, newValue
, 0, count
);
1064 * Return the number of code points between two indices in the
1065 * <code>StringBuffer</code>. An unpaired surrogate counts as a
1066 * code point for this purpose. Characters outside the indicated
1067 * range are not examined, even if the range ends in the middle of a
1070 * @param start the starting index
1071 * @param end one past the ending index
1072 * @return the number of code points
1075 public synchronized int codePointCount(int start
, int end
)
1077 if (start
< 0 || end
>= count
|| start
> end
)
1078 throw new StringIndexOutOfBoundsException();
1083 char base
= value
[start
];
1084 if (base
< Character
.MIN_HIGH_SURROGATE
1085 || base
> Character
.MAX_HIGH_SURROGATE
1088 || value
[start
+ 1] < Character
.MIN_LOW_SURROGATE
1089 || value
[start
+ 1] > Character
.MAX_LOW_SURROGATE
)
1105 * Starting at the given index, this counts forward by the indicated
1106 * number of code points, and then returns the resulting index. An
1107 * unpaired surrogate counts as a single code point for this
1110 * @param start the starting index
1111 * @param codePoints the number of code points
1112 * @return the resulting index
1115 public synchronized int offsetByCodePoints(int start
, int codePoints
)
1117 while (codePoints
> 0)
1119 char base
= value
[start
];
1120 if (base
< Character
.MIN_HIGH_SURROGATE
1121 || base
> Character
.MAX_HIGH_SURROGATE
1123 || value
[start
+ 1] < Character
.MIN_LOW_SURROGATE
1124 || value
[start
+ 1] > Character
.MAX_LOW_SURROGATE
)
1140 * An unsynchronized version of ensureCapacity, used internally to avoid
1141 * the cost of a second lock on the same object. This also has the side
1142 * effect of duplicating the array, if it was shared (to form copy-on-write
1145 * @param minimumCapacity the minimum capacity
1146 * @see #ensureCapacity(int)
1148 private void ensureCapacity_unsynchronized(int minimumCapacity
)
1150 if (shared
|| minimumCapacity
> value
.length
)
1152 // We don't want to make a larger vector when `shared' is
1153 // set. If we do, then setLength becomes very inefficient
1154 // when repeatedly reusing a StringBuffer in a loop.
1155 int max
= (minimumCapacity
> value
.length
1156 ? value
.length
* 2 + 2
1158 minimumCapacity
= (minimumCapacity
< max ? max
: minimumCapacity
);
1159 char[] nb
= new char[minimumCapacity
];
1160 VMSystem
.arraycopy(value
, 0, nb
, 0, count
);
1167 * Predicate which determines if a substring of this matches another String
1168 * starting at a specified offset for each String and continuing for a
1169 * specified length. This is more efficient than creating a String to call
1172 * @param toffset index to start comparison at for this String
1173 * @param other non-null String to compare to region of this
1174 * @return true if regions match, false otherwise
1175 * @see #indexOf(String, int)
1176 * @see #lastIndexOf(String, int)
1177 * @see String#regionMatches(boolean, int, String, int, int)
1179 private boolean regionMatches(int toffset
, String other
)
1181 int len
= other
.count
;
1182 int index
= other
.offset
;
1184 if (value
[toffset
++] != other
.value
[index
++])