1 /* StringBuffer.java -- Growable strings
2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
40 import java.io.Serializable;
43 * <code>StringBuffer</code> represents a changeable <code>String</code>.
44 * It provides the operations required to modify the
45 * <code>StringBuffer</code>, including insert, replace, delete, append,
46 * and reverse. It is thread-safe; meaning that all modifications to a buffer
47 * are in synchronized methods.
49 * <p><code>StringBuffer</code>s are variable-length in nature, so even if
50 * you initialize them to a certain size, they can still grow larger than
51 * that. <em>Capacity</em> indicates the number of characters the
52 * <code>StringBuffer</code> can have in it before it has to grow (growing
53 * the char array is an expensive operation involving <code>new</code>).
55 * <p>Incidentally, compilers often implement the String operator "+"
56 * by using a <code>StringBuffer</code> operation:<br>
57 * <code>a + b</code><br>
59 * <code>new StringBuffer().append(a).append(b).toString()</code>.
61 * <p>Classpath's StringBuffer is capable of sharing memory with Strings for
62 * efficiency. This will help when a StringBuffer is converted to a String
63 * and the StringBuffer is not changed after that (quite common when performing
64 * string concatenation).
69 * @author Eric Blake <ebb9@email.byu.edu>
72 * @status updated to 1.4
74 public final class StringBuffer implements Serializable, CharSequence
77 * Compatible with JDK 1.0+.
79 private static final long serialVersionUID = 3388685877147921107L;
82 * Index of next available character (and thus the size of the current
83 * string contents). Note that this has permissions set this way so that
84 * String can get the value.
86 * @serial the number of characters in the buffer
91 * The buffer. Note that this has permissions set this way so that String
99 * True if the buffer is shared with another object (StringBuffer or
100 * String); this means the buffer must be copied before writing to it again.
101 * Note that this has permissions set this way so that String can get the
104 * @serial whether the buffer is shared
109 * The default capacity of a buffer.
111 private final static int DEFAULT_CAPACITY = 16;
114 * Create a new StringBuffer with default capacity 16.
116 public StringBuffer()
118 this(DEFAULT_CAPACITY);
122 * Create an empty <code>StringBuffer</code> with the specified initial
125 * @param capacity the initial capacity
126 * @throws NegativeArraySizeException if capacity is negative
128 public StringBuffer(int capacity)
130 value = new char[capacity];
134 * Create a new <code>StringBuffer</code> with the characters in the
135 * specified <code>String</code>. Initial capacity will be the size of the
138 * @param str the <code>String</code> to convert
139 * @throws NullPointerException if str is null
141 public StringBuffer(String str)
143 // Unfortunately, because the size is 16 larger, we cannot share.
145 value = new char[count + DEFAULT_CAPACITY];
146 str.getChars(0, count, value, 0);
150 * Get the length of the <code>String</code> this <code>StringBuffer</code>
151 * would create. Not to be confused with the <em>capacity</em> of the
152 * <code>StringBuffer</code>.
154 * @return the length of this <code>StringBuffer</code>
156 * @see #setLength(int)
158 public synchronized int length()
164 * Get the total number of characters this <code>StringBuffer</code> can
165 * support before it must be grown. Not to be confused with <em>length</em>.
167 * @return the capacity of this <code>StringBuffer</code>
169 * @see #ensureCapacity(int)
171 public synchronized int capacity()
177 * Increase the capacity of this <code>StringBuffer</code>. This will
178 * ensure that an expensive growing operation will not occur until
179 * <code>minimumCapacity</code> is reached. The buffer is grown to the
180 * larger of <code>minimumCapacity</code> and
181 * <code>capacity() * 2 + 2</code>, if it is not already large enough.
183 * @param minimumCapacity the new capacity
186 public synchronized void ensureCapacity(int minimumCapacity)
188 ensureCapacity_unsynchronized(minimumCapacity);
192 * Set the length of this StringBuffer. If the new length is greater than
193 * the current length, all the new characters are set to '\0'. If the new
194 * length is less than the current length, the first <code>newLength</code>
195 * characters of the old array will be preserved, and the remaining
196 * characters are truncated.
198 * @param newLength the new length
199 * @throws IndexOutOfBoundsException if the new length is negative
200 * (while unspecified, this is a StringIndexOutOfBoundsException)
203 public synchronized void setLength(int newLength)
206 throw new StringIndexOutOfBoundsException(newLength);
208 ensureCapacity_unsynchronized(newLength);
209 while (count < newLength)
210 value[count++] = '\0';
215 * Get the character at the specified index.
217 * @param index the index of the character to get, starting at 0
218 * @return the character at the specified index
219 * @throws IndexOutOfBoundsException if index is negative or >= length()
220 * (while unspecified, this is a StringIndexOutOfBoundsException)
222 public synchronized char charAt(int index)
224 if (index < 0 || index >= count)
225 throw new StringIndexOutOfBoundsException(index);
230 * Get the specified array of characters. <code>srcOffset - srcEnd</code>
231 * characters will be copied into the array you pass in.
233 * @param srcOffset the index to start copying from (inclusive)
234 * @param srcEnd the index to stop copying from (exclusive)
235 * @param dst the array to copy into
236 * @param dstOffset the index to start copying into
237 * @throws NullPointerException if dst is null
238 * @throws IndexOutOfBoundsException if any source or target indices are
239 * out of range (while unspecified, source problems cause a
240 * StringIndexOutOfBoundsException, and dest problems cause an
241 * ArrayIndexOutOfBoundsException)
242 * @see System#arraycopy(Object, int, Object, int, int)
244 public synchronized void getChars(int srcOffset, int srcEnd,
245 char[] dst, int dstOffset)
247 if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset)
248 throw new StringIndexOutOfBoundsException();
249 System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset);
253 * Set the character at the specified index.
255 * @param index the index of the character to set starting at 0
256 * @param ch the value to set that character to
257 * @throws IndexOutOfBoundsException if index is negative or >= length()
258 * (while unspecified, this is a StringIndexOutOfBoundsException)
260 public synchronized void setCharAt(int index, char ch)
262 if (index < 0 || index >= count)
263 throw new StringIndexOutOfBoundsException(index);
264 // Call ensureCapacity to enforce copy-on-write.
265 ensureCapacity_unsynchronized(count);
270 * Append the <code>String</code> value of the argument to this
271 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
272 * to <code>String</code>.
274 * @param obj the <code>Object</code> to convert and append
275 * @return this <code>StringBuffer</code>
276 * @see String#valueOf(Object)
277 * @see #append(String)
279 public StringBuffer append(Object obj)
281 return append(obj == null ? "null" : obj.toString());
285 * Append the <code>String</code> to this <code>StringBuffer</code>. If
286 * str is null, the String "null" is appended.
288 * @param str the <code>String</code> to append
289 * @return this <code>StringBuffer</code>
291 public synchronized StringBuffer append(String str)
296 ensureCapacity_unsynchronized(count + len);
297 str.getChars(0, len, value, count);
303 * Append the <code>StringBuffer</code> value of the argument to this
304 * <code>StringBuffer</code>. This behaves the same as
305 * <code>append((Object) stringBuffer)</code>, except it is more efficient.
307 * @param stringBuffer the <code>StringBuffer</code> to convert and append
308 * @return this <code>StringBuffer</code>
309 * @see #append(Object)
312 public synchronized StringBuffer append(StringBuffer stringBuffer)
314 if (stringBuffer == null)
315 return append("null");
316 synchronized (stringBuffer)
318 int len = stringBuffer.count;
319 ensureCapacity_unsynchronized(count + len);
320 System.arraycopy(stringBuffer.value, 0, value, count, len);
327 * Append the <code>char</code> array to this <code>StringBuffer</code>.
328 * This is similar (but more efficient) than
329 * <code>append(new String(data))</code>, except in the case of null.
331 * @param data the <code>char[]</code> to append
332 * @return this <code>StringBuffer</code>
333 * @throws NullPointerException if <code>str</code> is <code>null</code>
334 * @see #append(char[], int, int)
336 public StringBuffer append(char[] data)
338 return append(data, 0, data.length);
342 * Append part of the <code>char</code> array to this
343 * <code>StringBuffer</code>. This is similar (but more efficient) than
344 * <code>append(new String(data, offset, count))</code>, except in the case
347 * @param data the <code>char[]</code> to append
348 * @param offset the start location in <code>str</code>
349 * @param count the number of characters to get from <code>str</code>
350 * @return this <code>StringBuffer</code>
351 * @throws NullPointerException if <code>str</code> is <code>null</code>
352 * @throws IndexOutOfBoundsException if offset or count is out of range
353 * (while unspecified, this is a StringIndexOutOfBoundsException)
355 public synchronized StringBuffer append(char[] data, int offset, int count)
357 if (offset < 0 || count < 0 || offset > data.length - count)
358 throw new StringIndexOutOfBoundsException();
359 ensureCapacity_unsynchronized(this.count + count);
360 System.arraycopy(data, offset, value, this.count, count);
366 * Append the <code>String</code> value of the argument to this
367 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
368 * to <code>String</code>.
370 * @param bool the <code>boolean</code> to convert and append
371 * @return this <code>StringBuffer</code>
372 * @see String#valueOf(boolean)
374 public StringBuffer append(boolean bool)
376 return append(bool ? "true" : "false");
380 * Append the <code>char</code> to this <code>StringBuffer</code>.
382 * @param c the <code>char</code> to append
383 * @return this <code>StringBuffer</code>
385 public synchronized StringBuffer append(char ch)
387 ensureCapacity_unsynchronized(count + 1);
393 * Append the <code>String</code> value of the argument to this
394 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
395 * to <code>String</code>.
397 * @param inum the <code>int</code> to convert and append
398 * @return this <code>StringBuffer</code>
399 * @see String#valueOf(int)
401 // GCJ LOCAL: this is native for efficiency.
402 public native StringBuffer append (int inum);
405 * Append the <code>String</code> value of the argument to this
406 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
407 * to <code>String</code>.
409 * @param lnum the <code>long</code> to convert and append
410 * @return this <code>StringBuffer</code>
411 * @see String#valueOf(long)
413 public StringBuffer append(long lnum)
415 return append(Long.toString(lnum, 10));
419 * Append the <code>String</code> value of the argument to this
420 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
421 * to <code>String</code>.
423 * @param fnum the <code>float</code> to convert and append
424 * @return this <code>StringBuffer</code>
425 * @see String#valueOf(float)
427 public StringBuffer append(float fnum)
429 return append(Float.toString(fnum));
433 * Append the <code>String</code> value of the argument to this
434 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
435 * to <code>String</code>.
437 * @param dnum the <code>double</code> to convert and append
438 * @return this <code>StringBuffer</code>
439 * @see String#valueOf(double)
441 public StringBuffer append(double dnum)
443 return append(Double.toString(dnum));
447 * Delete characters from this <code>StringBuffer</code>.
448 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
449 * harmless for end to be larger than length().
451 * @param start the first character to delete
452 * @param end the index after the last character to delete
453 * @return this <code>StringBuffer</code>
454 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
457 public synchronized StringBuffer delete(int start, int end)
459 if (start < 0 || start > count || start > end)
460 throw new StringIndexOutOfBoundsException(start);
463 // This will unshare if required.
464 ensureCapacity_unsynchronized(count);
465 if (count - end != 0)
466 System.arraycopy(value, end, value, start, count - end);
467 count -= end - start;
472 * Delete a character from this <code>StringBuffer</code>.
474 * @param index the index of the character to delete
475 * @return this <code>StringBuffer</code>
476 * @throws StringIndexOutOfBoundsException if index is out of bounds
479 public StringBuffer deleteCharAt(int index)
481 return delete(index, index + 1);
485 * Replace characters between index <code>start</code> (inclusive) and
486 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
487 * is larger than the size of this StringBuffer, all characters after
488 * <code>start</code> are replaced.
490 * @param start the beginning index of characters to delete (inclusive)
491 * @param end the ending index of characters to delete (exclusive)
492 * @param str the new <code>String</code> to insert
493 * @return this <code>StringBuffer</code>
494 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
495 * @throws NullPointerException if str is null
498 public synchronized StringBuffer replace(int start, int end, String str)
500 if (start < 0 || start > count || start > end)
501 throw new StringIndexOutOfBoundsException(start);
504 // Calculate the difference in 'count' after the replace.
505 int delta = len - (end > count ? count : end) + start;
506 ensureCapacity_unsynchronized(count + delta);
508 if (delta != 0 && end < count)
509 System.arraycopy(value, end, value, end + delta, count - end);
511 str.getChars(0, len, value, start);
517 * Creates a substring of this StringBuffer, starting at a specified index
518 * and ending at the end of this StringBuffer.
520 * @param beginIndex index to start substring (base 0)
521 * @return new String which is a substring of this StringBuffer
522 * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
523 * @see #substring(int, int)
526 public String substring(int beginIndex)
528 return substring(beginIndex, count);
532 * Creates a substring of this StringBuffer, starting at a specified index
533 * and ending at one character before a specified index. This is implemented
534 * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
535 * the CharSequence interface.
537 * @param beginIndex index to start at (inclusive, base 0)
538 * @param endIndex index to end at (exclusive)
539 * @return new String which is a substring of this StringBuffer
540 * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
542 * @see #substring(int, int)
545 public CharSequence subSequence(int beginIndex, int endIndex)
547 return substring(beginIndex, endIndex);
551 * Creates a substring of this StringBuffer, starting at a specified index
552 * and ending at one character before a specified index.
554 * @param beginIndex index to start at (inclusive, base 0)
555 * @param endIndex index to end at (exclusive)
556 * @return new String which is a substring of this StringBuffer
557 * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
561 public synchronized String substring(int beginIndex, int endIndex)
563 int len = endIndex - beginIndex;
564 if (beginIndex < 0 || endIndex > count || endIndex < beginIndex)
565 throw new StringIndexOutOfBoundsException();
568 // Don't copy unless substring is smaller than 1/4 of the buffer.
569 boolean share_buffer = ((len << 2) >= value.length);
572 // Package constructor avoids an array copy.
573 return new String(value, beginIndex, len, share_buffer);
577 * Insert a subarray of the <code>char[]</code> argument into this
578 * <code>StringBuffer</code>.
580 * @param offset the place to insert in this buffer
581 * @param str the <code>char[]</code> to insert
582 * @param str_offset the index in <code>str</code> to start inserting from
583 * @param len the number of characters to insert
584 * @return this <code>StringBuffer</code>
585 * @throws NullPointerException if <code>str</code> is <code>null</code>
586 * @throws StringIndexOutOfBoundsException if any index is out of bounds
589 public synchronized StringBuffer insert(int offset,
590 char[] str, int str_offset, int len)
592 if (offset < 0 || offset > count || len < 0
593 || str_offset < 0 || str_offset > str.length - len)
594 throw new StringIndexOutOfBoundsException();
595 ensureCapacity_unsynchronized(count + len);
596 System.arraycopy(value, offset, value, offset + len, count - offset);
597 System.arraycopy(str, str_offset, value, offset, len);
603 * Insert the <code>String</code> value of the argument into this
604 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
605 * to <code>String</code>.
607 * @param offset the place to insert in this buffer
608 * @param obj the <code>Object</code> to convert and insert
609 * @return this <code>StringBuffer</code>
610 * @exception StringIndexOutOfBoundsException if offset is out of bounds
611 * @see String#valueOf(Object)
613 public StringBuffer insert(int offset, Object obj)
615 return insert(offset, obj == null ? "null" : obj.toString());
619 * Insert the <code>String</code> argument into this
620 * <code>StringBuffer</code>. If str is null, the String "null" is used
623 * @param offset the place to insert in this buffer
624 * @param str the <code>String</code> to insert
625 * @return this <code>StringBuffer</code>
626 * @throws StringIndexOutOfBoundsException if offset is out of bounds
628 public synchronized StringBuffer insert(int offset, String str)
630 if (offset < 0 || offset > count)
631 throw new StringIndexOutOfBoundsException(offset);
635 ensureCapacity_unsynchronized(count + len);
636 System.arraycopy(value, offset, value, offset + len, count - offset);
637 str.getChars(0, len, value, offset);
643 * Insert the <code>char[]</code> argument into this
644 * <code>StringBuffer</code>.
646 * @param offset the place to insert in this buffer
647 * @param data the <code>char[]</code> to insert
648 * @return this <code>StringBuffer</code>
649 * @throws NullPointerException if <code>data</code> is <code>null</code>
650 * @throws StringIndexOutOfBoundsException if offset is out of bounds
651 * @see #insert(int, char[], int, int)
653 public StringBuffer insert(int offset, char[] data)
655 return insert(offset, data, 0, data.length);
659 * Insert the <code>String</code> value of the argument into this
660 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
661 * to <code>String</code>.
663 * @param offset the place to insert in this buffer
664 * @param bool the <code>boolean</code> to convert and insert
665 * @return this <code>StringBuffer</code>
666 * @throws StringIndexOutOfBoundsException if offset is out of bounds
667 * @see String#valueOf(boolean)
669 public StringBuffer insert(int offset, boolean bool)
671 return insert(offset, bool ? "true" : "false");
675 * Insert the <code>char</code> argument into this <code>StringBuffer</code>.
677 * @param offset the place to insert in this buffer
678 * @param ch the <code>char</code> to insert
679 * @return this <code>StringBuffer</code>
680 * @throws StringIndexOutOfBoundsException if offset is out of bounds
682 public synchronized StringBuffer insert(int offset, char ch)
684 if (offset < 0 || offset > count)
685 throw new StringIndexOutOfBoundsException(offset);
686 ensureCapacity_unsynchronized(count + 1);
687 System.arraycopy(value, offset, value, offset + 1, count - offset);
694 * Insert the <code>String</code> value of the argument into this
695 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
696 * to <code>String</code>.
698 * @param offset the place to insert in this buffer
699 * @param inum the <code>int</code> to convert and insert
700 * @return this <code>StringBuffer</code>
701 * @throws StringIndexOutOfBoundsException if offset is out of bounds
702 * @see String#valueOf(int)
704 public StringBuffer insert(int offset, int inum)
706 return insert(offset, String.valueOf(inum));
710 * Insert the <code>String</code> value of the argument into this
711 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
712 * to <code>String</code>.
714 * @param offset the place to insert in this buffer
715 * @param lnum the <code>long</code> to convert and insert
716 * @return this <code>StringBuffer</code>
717 * @throws StringIndexOutOfBoundsException if offset is out of bounds
718 * @see String#valueOf(long)
720 public StringBuffer insert(int offset, long lnum)
722 return insert(offset, Long.toString(lnum, 10));
726 * Insert the <code>String</code> value of the argument into this
727 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
728 * to <code>String</code>.
730 * @param offset the place to insert in this buffer
731 * @param fnum the <code>float</code> to convert and insert
732 * @return this <code>StringBuffer</code>
733 * @throws StringIndexOutOfBoundsException if offset is out of bounds
734 * @see String#valueOf(float)
736 public StringBuffer insert(int offset, float fnum)
738 return insert(offset, Float.toString(fnum));
742 * Insert the <code>String</code> value of the argument into this
743 * <code>StringBuffer</code>. Uses <code>String.valueOf()</code> to convert
744 * to <code>String</code>.
746 * @param offset the place to insert in this buffer
747 * @param dnum the <code>double</code> to convert and insert
748 * @return this <code>StringBuffer</code>
749 * @throws StringIndexOutOfBoundsException if offset is out of bounds
750 * @see String#valueOf(double)
752 public StringBuffer insert(int offset, double dnum)
754 return insert(offset, Double.toString(dnum));
758 * Finds the first instance of a substring in this StringBuffer.
760 * @param str String to find
761 * @return location (base 0) of the String, or -1 if not found
762 * @throws NullPointerException if str is null
763 * @see #indexOf(String, int)
766 public int indexOf(String str)
768 return indexOf(str, 0);
772 * Finds the first instance of a String in this StringBuffer, starting at
773 * a given index. If starting index is less than 0, the search starts at
774 * the beginning of this String. If the starting index is greater than the
775 * length of this String, or the substring is not found, -1 is returned.
777 * @param str String to find
778 * @param fromIndex index to start the search
779 * @return location (base 0) of the String, or -1 if not found
780 * @throws NullPointerException if str is null
783 public synchronized int indexOf(String str, int fromIndex)
787 int limit = count - str.count;
788 for ( ; fromIndex <= limit; fromIndex++)
789 if (regionMatches(fromIndex, str))
795 * Finds the last instance of a substring in this StringBuffer.
797 * @param str String to find
798 * @return location (base 0) of the String, or -1 if not found
799 * @throws NullPointerException if str is null
800 * @see #lastIndexOf(String, int)
803 public int lastIndexOf(String str)
805 return lastIndexOf(str, count - str.count);
809 * Finds the last instance of a String in this StringBuffer, starting at a
810 * given index. If starting index is greater than the maximum valid index,
811 * then the search begins at the end of this String. If the starting index
812 * is less than zero, or the substring is not found, -1 is returned.
814 * @param str String to find
815 * @param fromIndex index to start the search
816 * @return location (base 0) of the String, or -1 if not found
817 * @throws NullPointerException if str is null
820 public synchronized int lastIndexOf(String str, int fromIndex)
822 fromIndex = Math.min(fromIndex, count - str.count);
823 for ( ; fromIndex >= 0; fromIndex--)
824 if (regionMatches(fromIndex, str))
830 * Reverse the characters in this StringBuffer. The same sequence of
831 * characters exists, but in the reverse index ordering.
833 * @return this <code>StringBuffer</code>
835 public synchronized StringBuffer reverse()
837 // Call ensureCapacity to enforce copy-on-write.
838 ensureCapacity_unsynchronized(count);
839 for (int i = count >> 1, j = count - i; --i >= 0; ++j)
849 * Convert this <code>StringBuffer</code> to a <code>String</code>. The
850 * String is composed of the characters currently in this StringBuffer. Note
851 * that the result is a copy, and that future modifications to this buffer
852 * do not affect the String.
854 * @return the characters in this StringBuffer
856 public String toString()
858 // The string will set this.shared = true.
859 return new String(this);
863 * An unsynchronized version of ensureCapacity, used internally to avoid
864 * the cost of a second lock on the same object. This also has the side
865 * effect of duplicating the array, if it was shared (to form copy-on-write
868 * @param minimumCapacity the minimum capacity
869 * @see #ensureCapacity(int)
871 private void ensureCapacity_unsynchronized(int minimumCapacity)
873 if (shared || minimumCapacity > value.length)
875 // We don't want to make a larger vector when `shared' is
876 // set. If we do, then setLength becomes very inefficient
877 // when repeatedly reusing a StringBuffer in a loop.
878 int max = (minimumCapacity > value.length
879 ? value.length * 2 + 2
881 minimumCapacity = (minimumCapacity < max ? max : minimumCapacity);
882 char[] nb = new char[minimumCapacity];
883 System.arraycopy(value, 0, nb, 0, count);
890 * Predicate which determines if a substring of this matches another String
891 * starting at a specified offset for each String and continuing for a
892 * specified length. This is more efficient than creating a String to call
895 * @param toffset index to start comparison at for this String
896 * @param other non-null String to compare to region of this
897 * @return true if regions match, false otherwise
898 * @see #indexOf(String, int)
899 * @see #lastIndexOf(String, int)
900 * @see String#regionMatches(boolean, int, String, int, int)
902 // GCJ LOCAL: native for gcj.
903 private native boolean regionMatches(int toffset, String other);