Merge from mainline
[official-gcc.git] / libjava / java / lang / StringBuffer.java
blobc3f112967c415dec847d5e523e747bedb1e77b45
1 /* StringBuffer.java -- Growable strings
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
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)
10 any later version.
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
20 02110-1301 USA.
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
25 combination.
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. */
39 package java.lang;
41 import java.io.Serializable;
43 /**
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>
59 * is the same as<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).
67 * @author Paul Fisher
68 * @author John Keiser
69 * @author Tom Tromey
70 * @author Eric Blake (ebb9@email.byu.edu)
71 * @see String
72 * @since 1.0
73 * @status updated to 1.4
75 public final class StringBuffer implements Serializable, CharSequence
77 /**
78 * Compatible with JDK 1.0+.
80 private static final long serialVersionUID = 3388685877147921107L;
82 /**
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
89 int count;
91 /**
92 * The buffer. Note that this has permissions set this way so that String
93 * can get the value.
95 * @serial the buffer
97 char[] value;
99 /**
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
103 * value.
105 * @serial whether the buffer is shared
107 boolean 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
124 * capacity.
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
137 * String plus 16.
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.
145 count = str.count;
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
158 * @since 1.5
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>
174 * @see #capacity()
175 * @see #setLength(int)
177 public synchronized int length()
179 return count;
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>
187 * @see #length()
188 * @see #ensureCapacity(int)
190 public synchronized int capacity()
192 return value.length;
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
203 * @see #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)
220 * @see #length()
222 public synchronized void setLength(int newLength)
224 if (newLength < 0)
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'. */
238 count = newLength;
240 else
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 &gt;= length()
256 public synchronized char charAt(int index)
258 if (index < 0 || index >= count)
259 throw new StringIndexOutOfBoundsException(index);
260 return value[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 &gt;= length()
271 * @since 1.5
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 &gt;= length()
285 * @since 1.5
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.
291 if (index >= count)
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 System.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 &gt;= 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);
333 value[index] = ch;
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)
360 if (str == null)
361 str = "null";
362 int len = str.count;
363 ensureCapacity_unsynchronized(count + len);
364 str.getChars(0, len, value, count);
365 count += len;
366 return this;
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)
377 * @since 1.4
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 System.arraycopy(stringBuffer.value, 0, value, count, len);
388 count += len;
390 return this;
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)
400 * @since 1.5
402 public synchronized StringBuffer append(CharSequence sequence)
404 if (sequence == null)
405 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)
418 * @since 1.5
420 public synchronized StringBuffer append(CharSequence sequence,
421 int start, int end)
423 if (sequence == null)
424 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);
430 return this;
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
452 * of null.
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 System.arraycopy(data, offset, value, this.count, count);
468 this.count += count;
469 return this;
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);
495 value[count++] = ch;
496 return this;
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)
507 * @since 1.5
509 public synchronized StringBuffer appendCodePoint(int code)
511 int len = Character.charCount(code);
512 ensureCapacity_unsynchronized(count + len);
513 Character.toChars(code, value, count);
514 count += len;
515 return this;
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 // GCJ LOCAL: this is native for efficiency.
528 public native StringBuffer append (int inum);
531 * Append the <code>String</code> value of the argument to this
532 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
533 * to <code>String</code>.
535 * @param lnum the <code>long</code> to convert and append
536 * @return this <code>StringBuffer</code>
537 * @see String#valueOf(long)
539 public StringBuffer append(long lnum)
541 return append(Long.toString(lnum, 10));
545 * Append the <code>String</code> value of the argument to this
546 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
547 * to <code>String</code>.
549 * @param fnum the <code>float</code> to convert and append
550 * @return this <code>StringBuffer</code>
551 * @see String#valueOf(float)
553 public StringBuffer append(float fnum)
555 return append(Float.toString(fnum));
559 * Append the <code>String</code> value of the argument to this
560 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
561 * to <code>String</code>.
563 * @param dnum the <code>double</code> to convert and append
564 * @return this <code>StringBuffer</code>
565 * @see String#valueOf(double)
567 public StringBuffer append(double dnum)
569 return append(Double.toString(dnum));
573 * Delete characters from this <code>StringBuffer</code>.
574 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
575 * harmless for end to be larger than length().
577 * @param start the first character to delete
578 * @param end the index after the last character to delete
579 * @return this <code>StringBuffer</code>
580 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
581 * @since 1.2
583 public synchronized StringBuffer delete(int start, int end)
585 if (start < 0 || start > count || start > end)
586 throw new StringIndexOutOfBoundsException(start);
587 if (end > count)
588 end = count;
589 // This will unshare if required.
590 ensureCapacity_unsynchronized(count);
591 if (count - end != 0)
592 System.arraycopy(value, end, value, start, count - end);
593 count -= end - start;
594 return this;
598 * Delete a character from this <code>StringBuffer</code>.
600 * @param index the index of the character to delete
601 * @return this <code>StringBuffer</code>
602 * @throws StringIndexOutOfBoundsException if index is out of bounds
603 * @since 1.2
605 public StringBuffer deleteCharAt(int index)
607 return delete(index, index + 1);
611 * Replace characters between index <code>start</code> (inclusive) and
612 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
613 * is larger than the size of this StringBuffer, all characters after
614 * <code>start</code> are replaced.
616 * @param start the beginning index of characters to delete (inclusive)
617 * @param end the ending index of characters to delete (exclusive)
618 * @param str the new <code>String</code> to insert
619 * @return this <code>StringBuffer</code>
620 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
621 * @throws NullPointerException if str is null
622 * @since 1.2
624 public synchronized StringBuffer replace(int start, int end, String str)
626 if (start < 0 || start > count || start > end)
627 throw new StringIndexOutOfBoundsException(start);
629 int len = str.count;
630 // Calculate the difference in 'count' after the replace.
631 int delta = len - (end > count ? count : end) + start;
632 ensureCapacity_unsynchronized(count + delta);
634 if (delta != 0 && end < count)
635 System.arraycopy(value, end, value, end + delta, count - end);
637 str.getChars(0, len, value, start);
638 count += delta;
639 return this;
643 * Creates a substring of this StringBuffer, starting at a specified index
644 * and ending at the end of this StringBuffer.
646 * @param beginIndex index to start substring (base 0)
647 * @return new String which is a substring of this StringBuffer
648 * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
649 * @see #substring(int, int)
650 * @since 1.2
652 public String substring(int beginIndex)
654 return substring(beginIndex, count);
658 * Creates a substring of this StringBuffer, starting at a specified index
659 * and ending at one character before a specified index. This is implemented
660 * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
661 * the CharSequence interface.
663 * @param beginIndex index to start at (inclusive, base 0)
664 * @param endIndex index to end at (exclusive)
665 * @return new String which is a substring of this StringBuffer
666 * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
667 * bounds
668 * @see #substring(int, int)
669 * @since 1.4
671 public CharSequence subSequence(int beginIndex, int endIndex)
673 return substring(beginIndex, endIndex);
677 * Creates a substring of this StringBuffer, starting at a specified index
678 * and ending at one character before a specified index.
680 * @param beginIndex index to start at (inclusive, base 0)
681 * @param endIndex index to end at (exclusive)
682 * @return new String which is a substring of this StringBuffer
683 * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
684 * of bounds
685 * @since 1.2
687 public synchronized String substring(int beginIndex, int endIndex)
689 int len = endIndex - beginIndex;
690 if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
691 throw new StringIndexOutOfBoundsException();
692 if (len == 0)
693 return "";
694 // Don't copy unless substring is smaller than 1/4 of the buffer.
695 boolean share_buffer = ((len << 2) >= value.length);
696 if (share_buffer)
697 this.shared = true;
698 // Package constructor avoids an array copy.
699 return new String(value, beginIndex, len, share_buffer);
703 * Insert a subarray of the <code>char[]</code> argument into this
704 * <code>StringBuffer</code>.
706 * @param offset the place to insert in this buffer
707 * @param str the <code>char[]</code> to insert
708 * @param str_offset the index in <code>str</code> to start inserting from
709 * @param len the number of characters to insert
710 * @return this <code>StringBuffer</code>
711 * @throws NullPointerException if <code>str</code> is <code>null</code>
712 * @throws StringIndexOutOfBoundsException if any index is out of bounds
713 * @since 1.2
715 public synchronized StringBuffer insert(int offset,
716 char[] str, int str_offset, int len)
718 if (offset < 0 || offset > count || len < 0
719 || str_offset < 0 || str_offset > str.length - len)
720 throw new StringIndexOutOfBoundsException();
721 ensureCapacity_unsynchronized(count + len);
722 System.arraycopy(value, offset, value, offset + len, count - offset);
723 System.arraycopy(str, str_offset, value, offset, len);
724 count += len;
725 return this;
729 * Insert the <code>String</code> value of the argument into this
730 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
731 * to <code>String</code>.
733 * @param offset the place to insert in this buffer
734 * @param obj the <code>Object</code> to convert and insert
735 * @return this <code>StringBuffer</code>
736 * @exception StringIndexOutOfBoundsException if offset is out of bounds
737 * @see String#valueOf(Object)
739 public StringBuffer insert(int offset, Object obj)
741 return insert(offset, obj == null ? "null" : obj.toString());
745 * Insert the <code>String</code> argument into this
746 * <code>StringBuffer</code>. If str is null, the String "null" is used
747 * instead.
749 * @param offset the place to insert in this buffer
750 * @param str the <code>String</code> to insert
751 * @return this <code>StringBuffer</code>
752 * @throws StringIndexOutOfBoundsException if offset is out of bounds
754 public synchronized StringBuffer insert(int offset, String str)
756 if (offset < 0 || offset > count)
757 throw new StringIndexOutOfBoundsException(offset);
758 if (str == null)
759 str = "null";
760 int len = str.count;
761 ensureCapacity_unsynchronized(count + len);
762 System.arraycopy(value, offset, value, offset + len, count - offset);
763 str.getChars(0, len, value, offset);
764 count += len;
765 return this;
769 * Insert the <code>CharSequence</code> argument into this
770 * <code>StringBuffer</code>. If the sequence is null, the String
771 * "null" is used instead.
773 * @param offset the place to insert in this buffer
774 * @param sequence the <code>CharSequence</code> to insert
775 * @return this <code>StringBuffer</code>
776 * @throws IndexOutOfBoundsException if offset is out of bounds
777 * @since 1.5
779 public synchronized StringBuffer insert(int offset, CharSequence sequence)
781 if (sequence == null)
782 sequence = "null";
783 return insert(offset, sequence, 0, sequence.length());
787 * Insert a subsequence of the <code>CharSequence</code> argument into this
788 * <code>StringBuffer</code>. If the sequence is null, the String
789 * "null" is used instead.
791 * @param offset the place to insert in this buffer
792 * @param sequence the <code>CharSequence</code> to insert
793 * @param start the starting index of the subsequence
794 * @param end one past the ending index of the subsequence
795 * @return this <code>StringBuffer</code>
796 * @throws IndexOutOfBoundsException if offset, start,
797 * or end are out of bounds
798 * @since 1.5
800 public synchronized StringBuffer insert(int offset, CharSequence sequence,
801 int start, int end)
803 if (sequence == null)
804 sequence = "null";
805 if (start < 0 || end < 0 || start > end || end > sequence.length())
806 throw new IndexOutOfBoundsException();
807 int len = end - start;
808 ensureCapacity_unsynchronized(count + len);
809 System.arraycopy(value, offset, value, offset + len, count - offset);
810 for (int i = start; i < end; ++i)
811 value[offset++] = sequence.charAt(i);
812 count += len;
813 return this;
817 * Insert the <code>char[]</code> argument into this
818 * <code>StringBuffer</code>.
820 * @param offset the place to insert in this buffer
821 * @param data the <code>char[]</code> to insert
822 * @return this <code>StringBuffer</code>
823 * @throws NullPointerException if <code>data</code> is <code>null</code>
824 * @throws StringIndexOutOfBoundsException if offset is out of bounds
825 * @see #insert(int, char[], int, int)
827 public StringBuffer insert(int offset, char[] data)
829 return insert(offset, data, 0, data.length);
833 * Insert the <code>String</code> value of the argument into this
834 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
835 * to <code>String</code>.
837 * @param offset the place to insert in this buffer
838 * @param bool the <code>boolean</code> to convert and insert
839 * @return this <code>StringBuffer</code>
840 * @throws StringIndexOutOfBoundsException if offset is out of bounds
841 * @see String#valueOf(boolean)
843 public StringBuffer insert(int offset, boolean bool)
845 return insert(offset, bool ? "true" : "false");
849 * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
851 * @param offset the place to insert in this buffer
852 * @param ch the <code>char</code> to insert
853 * @return this <code>StringBuffer</code>
854 * @throws StringIndexOutOfBoundsException if offset is out of bounds
856 public synchronized StringBuffer insert(int offset, char ch)
858 if (offset < 0 || offset > count)
859 throw new StringIndexOutOfBoundsException(offset);
860 ensureCapacity_unsynchronized(count + 1);
861 System.arraycopy(value, offset, value, offset + 1, count - offset);
862 value[offset] = ch;
863 count++;
864 return this;
868 * Insert the <code>String</code> value of the argument into this
869 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
870 * to <code>String</code>.
872 * @param offset the place to insert in this buffer
873 * @param inum the <code>int</code> to convert and insert
874 * @return this <code>StringBuffer</code>
875 * @throws StringIndexOutOfBoundsException if offset is out of bounds
876 * @see String#valueOf(int)
878 public StringBuffer insert(int offset, int inum)
880 return insert(offset, String.valueOf(inum));
884 * Insert the <code>String</code> value of the argument into this
885 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
886 * to <code>String</code>.
888 * @param offset the place to insert in this buffer
889 * @param lnum the <code>long</code> to convert and insert
890 * @return this <code>StringBuffer</code>
891 * @throws StringIndexOutOfBoundsException if offset is out of bounds
892 * @see String#valueOf(long)
894 public StringBuffer insert(int offset, long lnum)
896 return insert(offset, Long.toString(lnum, 10));
900 * Insert the <code>String</code> value of the argument into this
901 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
902 * to <code>String</code>.
904 * @param offset the place to insert in this buffer
905 * @param fnum the <code>float</code> to convert and insert
906 * @return this <code>StringBuffer</code>
907 * @throws StringIndexOutOfBoundsException if offset is out of bounds
908 * @see String#valueOf(float)
910 public StringBuffer insert(int offset, float fnum)
912 return insert(offset, Float.toString(fnum));
916 * Insert the <code>String</code> value of the argument into this
917 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
918 * to <code>String</code>.
920 * @param offset the place to insert in this buffer
921 * @param dnum the <code>double</code> to convert and insert
922 * @return this <code>StringBuffer</code>
923 * @throws StringIndexOutOfBoundsException if offset is out of bounds
924 * @see String#valueOf(double)
926 public StringBuffer insert(int offset, double dnum)
928 return insert(offset, Double.toString(dnum));
932 * Finds the first instance of a substring in this StringBuffer.
934 * @param str String to find
935 * @return location (base 0) of the String, or -1 if not found
936 * @throws NullPointerException if str is null
937 * @see #indexOf(String, int)
938 * @since 1.4
940 public int indexOf(String str)
942 return indexOf(str, 0);
946 * Finds the first instance of a String in this StringBuffer, starting at
947 * a given index. If starting index is less than 0, the search starts at
948 * the beginning of this String. If the starting index is greater than the
949 * length of this String, or the substring is not found, -1 is returned.
951 * @param str String to find
952 * @param fromIndex index to start the search
953 * @return location (base 0) of the String, or -1 if not found
954 * @throws NullPointerException if str is null
955 * @since 1.4
957 public synchronized int indexOf(String str, int fromIndex)
959 if (fromIndex < 0)
960 fromIndex = 0;
961 int limit = count - str.count;
962 for ( ; fromIndex <= limit; fromIndex++)
963 if (regionMatches(fromIndex, str))
964 return fromIndex;
965 return -1;
969 * Finds the last instance of a substring in this StringBuffer.
971 * @param str String to find
972 * @return location (base 0) of the String, or -1 if not found
973 * @throws NullPointerException if str is null
974 * @see #lastIndexOf(String, int)
975 * @since 1.4
977 public int lastIndexOf(String str)
979 return lastIndexOf(str, count - str.count);
983 * Finds the last instance of a String in this StringBuffer, starting at a
984 * given index. If starting index is greater than the maximum valid index,
985 * then the search begins at the end of this String. If the starting index
986 * is less than zero, or the substring is not found, -1 is returned.
988 * @param str String to find
989 * @param fromIndex index to start the search
990 * @return location (base 0) of the String, or -1 if not found
991 * @throws NullPointerException if str is null
992 * @since 1.4
994 public synchronized int lastIndexOf(String str, int fromIndex)
996 fromIndex = Math.min(fromIndex, count - str.count);
997 for ( ; fromIndex >= 0; fromIndex--)
998 if (regionMatches(fromIndex, str))
999 return fromIndex;
1000 return -1;
1004 * Reverse the characters in this StringBuffer. The same sequence of
1005 * characters exists, but in the reverse index ordering.
1007 * @return this <code>StringBuffer</code>
1009 public synchronized StringBuffer reverse()
1011 // Call ensureCapacity to enforce copy-on-write.
1012 ensureCapacity_unsynchronized(count);
1013 for (int i = count >> 1, j = count - i; --i >= 0; ++j)
1015 char c = value[i];
1016 value[i] = value[j];
1017 value[j] = c;
1019 return this;
1023 * Convert this <code>StringBuffer</code> to a <code>String</code>. The
1024 * String is composed of the characters currently in this StringBuffer. Note
1025 * that the result is a copy, and that future modifications to this buffer
1026 * do not affect the String.
1028 * @return the characters in this StringBuffer
1030 public String toString()
1032 // The string will set this.shared = true.
1033 return new String(this);
1037 * This may reduce the amount of memory used by the StringBuffer,
1038 * by resizing the internal array to remove unused space. However,
1039 * this method is not required to resize, so this behavior cannot
1040 * be relied upon.
1041 * @since 1.5
1043 public synchronized void trimToSize()
1045 int wouldSave = value.length - count;
1046 // Some random heuristics: if we save less than 20 characters, who
1047 // cares.
1048 if (wouldSave < 20)
1049 return;
1050 // If we save more than 200 characters, shrink.
1051 // If we save more than 1/4 of the buffer, shrink.
1052 if (wouldSave > 200 || wouldSave * 4 > value.length)
1054 char[] newValue = new char[count];
1055 System.arraycopy(value, 0, newValue, 0, count);
1056 value = newValue;
1061 * Return the number of code points between two indices in the
1062 * <code>StringBuffer</code>. An unpaired surrogate counts as a
1063 * code point for this purpose. Characters outside the indicated
1064 * range are not examined, even if the range ends in the middle of a
1065 * surrogate pair.
1067 * @param start the starting index
1068 * @param end one past the ending index
1069 * @return the number of code points
1070 * @since 1.5
1072 public synchronized int codePointCount(int start, int end)
1074 if (start < 0 || end >= count || start > end)
1075 throw new StringIndexOutOfBoundsException();
1077 int count = 0;
1078 while (start < end)
1080 char base = value[start];
1081 if (base < Character.MIN_HIGH_SURROGATE
1082 || base > Character.MAX_HIGH_SURROGATE
1083 || start == end
1084 || start == count
1085 || value[start + 1] < Character.MIN_LOW_SURROGATE
1086 || value[start + 1] > Character.MAX_LOW_SURROGATE)
1088 // Nothing.
1090 else
1092 // Surrogate pair.
1093 ++start;
1095 ++start;
1096 ++count;
1098 return count;
1102 * Starting at the given index, this counts forward by the indicated
1103 * number of code points, and then returns the resulting index. An
1104 * unpaired surrogate counts as a single code point for this
1105 * purpose.
1107 * @param start the starting index
1108 * @param codePoints the number of code points
1109 * @return the resulting index
1110 * @since 1.5
1112 public synchronized int offsetByCodePoints(int start, int codePoints)
1114 while (codePoints > 0)
1116 char base = value[start];
1117 if (base < Character.MIN_HIGH_SURROGATE
1118 || base > Character.MAX_HIGH_SURROGATE
1119 || start == count
1120 || value[start + 1] < Character.MIN_LOW_SURROGATE
1121 || value[start + 1] > Character.MAX_LOW_SURROGATE)
1123 // Nothing.
1125 else
1127 // Surrogate pair.
1128 ++start;
1130 ++start;
1131 --codePoints;
1133 return start;
1137 * An unsynchronized version of ensureCapacity, used internally to avoid
1138 * the cost of a second lock on the same object. This also has the side
1139 * effect of duplicating the array, if it was shared (to form copy-on-write
1140 * semantics).
1142 * @param minimumCapacity the minimum capacity
1143 * @see #ensureCapacity(int)
1145 private void ensureCapacity_unsynchronized(int minimumCapacity)
1147 if (shared || minimumCapacity > value.length)
1149 // We don't want to make a larger vector when `shared' is
1150 // set. If we do, then setLength becomes very inefficient
1151 // when repeatedly reusing a StringBuffer in a loop.
1152 int max = (minimumCapacity > value.length
1153 ? value.length * 2 + 2
1154 : value.length);
1155 minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
1156 char[] nb = new char[minimumCapacity];
1157 System.arraycopy(value, 0, nb, 0, count);
1158 value = nb;
1159 shared = false;
1164 * Predicate which determines if a substring of this matches another String
1165 * starting at a specified offset for each String and continuing for a
1166 * specified length. This is more efficient than creating a String to call
1167 * indexOf on.
1169 * @param toffset index to start comparison at for this String
1170 * @param other non-null String to compare to region of this
1171 * @return true if regions match, false otherwise
1172 * @see #indexOf(String, int)
1173 * @see #lastIndexOf(String, int)
1174 * @see String#regionMatches(boolean, int, String, int, int)
1176 // GCJ LOCAL: native for gcj.
1177 private native boolean regionMatches(int toffset, String other);