1 /* StringBuilder.java -- Unsynchronized 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>StringBuilder</code> represents a changeable <code>String</code>.
45 * It provides the operations required to modify the
46 * <code>StringBuilder</code>, including insert, replace, delete, append,
47 * and reverse. It like <code>StringBuffer</code>, but is not
48 * synchronized. It is ideal for use when it is known that the
49 * object will only be used from a single thread.
51 * <p><code>StringBuilder</code>s are variable-length in nature, so even if
52 * you initialize them to a certain size, they can still grow larger than
53 * that. <em>Capacity</em> indicates the number of characters the
54 * <code>StringBuilder</code> can have in it before it has to grow (growing
55 * the char array is an expensive operation involving <code>new</code>).
57 * <p>Incidentally, compilers often implement the String operator "+"
58 * by using a <code>StringBuilder</code> operation:<br>
59 * <code>a + b</code><br>
61 * <code>new StringBuilder().append(a).append(b).toString()</code>.
63 * <p>Classpath's StringBuilder is capable of sharing memory with Strings for
64 * efficiency. This will help when a StringBuilder is converted to a String
65 * and the StringBuilder is not changed after that (quite common when
66 * performing string concatenation).
71 * @author Eric Blake (ebb9@email.byu.edu)
77 // FIX15: Implement Appendable when co-variant methods are available
78 public final class StringBuilder
79 implements Serializable
, CharSequence
81 // Implementation note: if you change this class, you usually will
82 // want to change StringBuffer as well.
85 * For compatability with Sun's JDK
87 private static final long serialVersionUID
= 4383685877147921099L;
90 * Index of next available character (and thus the size of the current
91 * string contents). Note that this has permissions set this way so that
92 * String can get the value.
94 * @serial the number of characters in the buffer
99 * The buffer. Note that this has permissions set this way so that String
107 * The default capacity of a buffer.
109 private static final int DEFAULT_CAPACITY
= 16;
112 * Create a new StringBuilder with default capacity 16.
114 public StringBuilder()
116 this(DEFAULT_CAPACITY
);
120 * Create an empty <code>StringBuilder</code> with the specified initial
123 * @param capacity the initial capacity
124 * @throws NegativeArraySizeException if capacity is negative
126 public StringBuilder(int capacity
)
128 value
= new char[capacity
];
132 * Create a new <code>StringBuilder</code> with the characters in the
133 * specified <code>String</code>. Initial capacity will be the size of the
136 * @param str the <code>String</code> to convert
137 * @throws NullPointerException if str is null
139 public StringBuilder(String str
)
141 // Unfortunately, because the size is 16 larger, we cannot share.
143 value
= new char[count
+ DEFAULT_CAPACITY
];
144 str
.getChars(0, count
, value
, 0);
148 * Create a new <code>StringBuilder</code> with the characters in the
149 * specified <code>CharSequence</code>. Initial capacity will be the
150 * length of the sequence plus 16; if the sequence reports a length
151 * less than or equal to 0, then the initial capacity will be 16.
153 * @param seq the initializing <code>CharSequence</code>
154 * @throws NullPointerException if str is null
156 public StringBuilder(CharSequence seq
)
158 int len
= seq
.length();
159 count
= len
<= 0 ?
0 : len
;
160 value
= new char[count
+ DEFAULT_CAPACITY
];
161 for (int i
= 0; i
< len
; ++i
)
162 value
[i
] = seq
.charAt(i
);
166 * Get the length of the <code>String</code> this <code>StringBuilder</code>
167 * would create. Not to be confused with the <em>capacity</em> of the
168 * <code>StringBuilder</code>.
170 * @return the length of this <code>StringBuilder</code>
172 * @see #setLength(int)
180 * Get the total number of characters this <code>StringBuilder</code> can
181 * support before it must be grown. Not to be confused with <em>length</em>.
183 * @return the capacity of this <code>StringBuilder</code>
185 * @see #ensureCapacity(int)
187 public int capacity()
193 * Increase the capacity of this <code>StringBuilder</code>. This will
194 * ensure that an expensive growing operation will not occur until
195 * <code>minimumCapacity</code> is reached. The buffer is grown to the
196 * larger of <code>minimumCapacity</code> and
197 * <code>capacity() * 2 + 2</code>, if it is not already large enough.
199 * @param minimumCapacity the new capacity
202 public void ensureCapacity(int minimumCapacity
)
204 if (minimumCapacity
> value
.length
)
206 int max
= value
.length
* 2 + 2;
207 minimumCapacity
= (minimumCapacity
< max ? max
: minimumCapacity
);
208 char[] nb
= new char[minimumCapacity
];
209 System
.arraycopy(value
, 0, nb
, 0, count
);
215 * Set the length of this StringBuilder. If the new length is greater than
216 * the current length, all the new characters are set to '\0'. If the new
217 * length is less than the current length, the first <code>newLength</code>
218 * characters of the old array will be preserved, and the remaining
219 * characters are truncated.
221 * @param newLength the new length
222 * @throws IndexOutOfBoundsException if the new length is negative
223 * (while unspecified, this is a StringIndexOutOfBoundsException)
226 public void setLength(int newLength
)
229 throw new StringIndexOutOfBoundsException(newLength
);
231 int valueLength
= value
.length
;
233 /* Always call ensureCapacity in order to preserve copy-on-write
235 ensureCapacity(newLength
);
237 if (newLength
< valueLength
)
239 /* If the StringBuilder's value just grew, then we know that
240 value is newly allocated and the region between count and
241 newLength is filled with '\0'. */
246 /* The StringBuilder's value doesn't need to grow. However,
247 we should clear out any cruft that may exist. */
248 while (count
< newLength
)
249 value
[count
++] = '\0';
254 * Get the character at the specified index.
256 * @param index the index of the character to get, starting at 0
257 * @return the character at the specified index
258 * @throws IndexOutOfBoundsException if index is negative or >= length()
259 * (while unspecified, this is a StringIndexOutOfBoundsException)
261 public char charAt(int index
)
263 if (index
< 0 || index
>= count
)
264 throw new StringIndexOutOfBoundsException(index
);
269 * Get the specified array of characters. <code>srcOffset - srcEnd</code>
270 * characters will be copied into the array you pass in.
272 * @param srcOffset the index to start copying from (inclusive)
273 * @param srcEnd the index to stop copying from (exclusive)
274 * @param dst the array to copy into
275 * @param dstOffset the index to start copying into
276 * @throws NullPointerException if dst is null
277 * @throws IndexOutOfBoundsException if any source or target indices are
278 * out of range (while unspecified, source problems cause a
279 * StringIndexOutOfBoundsException, and dest problems cause an
280 * ArrayIndexOutOfBoundsException)
281 * @see System#arraycopy(Object, int, Object, int, int)
283 public void getChars(int srcOffset
, int srcEnd
,
284 char[] dst
, int dstOffset
)
286 if (srcOffset
< 0 || srcEnd
> count
|| srcEnd
< srcOffset
)
287 throw new StringIndexOutOfBoundsException();
288 System
.arraycopy(value
, srcOffset
, dst
, dstOffset
, srcEnd
- srcOffset
);
292 * Set the character at the specified index.
294 * @param index the index of the character to set starting at 0
295 * @param ch the value to set that character to
296 * @throws IndexOutOfBoundsException if index is negative or >= length()
297 * (while unspecified, this is a StringIndexOutOfBoundsException)
299 public void setCharAt(int index
, char ch
)
301 if (index
< 0 || index
>= count
)
302 throw new StringIndexOutOfBoundsException(index
);
303 // Call ensureCapacity to enforce copy-on-write.
304 ensureCapacity(count
);
309 * Append the <code>String</code> value of the argument to this
310 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
311 * to <code>String</code>.
313 * @param obj the <code>Object</code> to convert and append
314 * @return this <code>StringBuilder</code>
315 * @see String#valueOf(Object)
316 * @see #append(String)
318 public StringBuilder
append(Object obj
)
320 return append(obj
== null ?
"null" : obj
.toString());
324 * Append the <code>String</code> to this <code>StringBuilder</code>. If
325 * str is null, the String "null" is appended.
327 * @param str the <code>String</code> to append
328 * @return this <code>StringBuilder</code>
330 public StringBuilder
append(String str
)
335 ensureCapacity(count
+ len
);
336 str
.getChars(0, len
, value
, count
);
342 * Append the <code>StringBuilder</code> value of the argument to this
343 * <code>StringBuilder</code>. This behaves the same as
344 * <code>append((Object) stringBuffer)</code>, except it is more efficient.
346 * @param stringBuffer the <code>StringBuilder</code> to convert and append
347 * @return this <code>StringBuilder</code>
348 * @see #append(Object)
350 public StringBuilder
append(StringBuffer stringBuffer
)
352 if (stringBuffer
== null)
353 return append("null");
354 synchronized (stringBuffer
)
356 int len
= stringBuffer
.count
;
357 ensureCapacity(count
+ len
);
358 System
.arraycopy(stringBuffer
.value
, 0, value
, count
, len
);
365 * Append the <code>char</code> array to this <code>StringBuilder</code>.
366 * This is similar (but more efficient) than
367 * <code>append(new String(data))</code>, except in the case of null.
369 * @param data the <code>char[]</code> to append
370 * @return this <code>StringBuilder</code>
371 * @throws NullPointerException if <code>str</code> is <code>null</code>
372 * @see #append(char[], int, int)
374 public StringBuilder
append(char[] data
)
376 return append(data
, 0, data
.length
);
380 * Append part of the <code>char</code> array to this
381 * <code>StringBuilder</code>. This is similar (but more efficient) than
382 * <code>append(new String(data, offset, count))</code>, except in the case
385 * @param data the <code>char[]</code> to append
386 * @param offset the start location in <code>str</code>
387 * @param count the number of characters to get from <code>str</code>
388 * @return this <code>StringBuilder</code>
389 * @throws NullPointerException if <code>str</code> is <code>null</code>
390 * @throws IndexOutOfBoundsException if offset or count is out of range
391 * (while unspecified, this is a StringIndexOutOfBoundsException)
393 public StringBuilder
append(char[] data
, int offset
, int count
)
395 if (offset
< 0 || count
< 0 || offset
> data
.length
- count
)
396 throw new StringIndexOutOfBoundsException();
397 ensureCapacity(this.count
+ count
);
398 System
.arraycopy(data
, offset
, value
, this.count
, count
);
404 * Append the <code>String</code> value of the argument to this
405 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
406 * to <code>String</code>.
408 * @param bool the <code>boolean</code> to convert and append
409 * @return this <code>StringBuilder</code>
410 * @see String#valueOf(boolean)
412 public StringBuilder
append(boolean bool
)
414 return append(bool ?
"true" : "false");
418 * Append the <code>char</code> to this <code>StringBuilder</code>.
420 * @param ch the <code>char</code> to append
421 * @return this <code>StringBuilder</code>
423 public StringBuilder
append(char ch
)
425 ensureCapacity(count
+ 1);
431 * Append the characters in the <code>CharSequence</code> to this
434 * @param seq the <code>CharSequence</code> providing the characters
435 * @return this <code>StringBuilder</code>
437 public StringBuilder
append(CharSequence seq
)
439 return append(seq
, 0, seq
.length());
443 * Append some characters from the <code>CharSequence</code> to this
444 * buffer. If the argument is null, the four characters "null" are
447 * @param seq the <code>CharSequence</code> providing the characters
448 * @param start the starting index
449 * @param end one past the final index
450 * @return this <code>StringBuilder</code>
452 public StringBuilder
append(CharSequence seq
, int start
,
456 return append("null");
459 ensureCapacity(count
+ end
- start
);
460 for (; start
< end
; ++start
)
461 value
[count
++] = seq
.charAt(start
);
467 * Append the <code>String</code> value of the argument to this
468 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
469 * to <code>String</code>.
471 * @param inum the <code>int</code> to convert and append
472 * @return this <code>StringBuilder</code>
473 * @see String#valueOf(int)
475 // FIXME: this is native in libgcj in StringBuffer.
476 public StringBuilder
append(int inum
)
478 return append(String
.valueOf(inum
));
482 * Append the <code>String</code> value of the argument to this
483 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
484 * to <code>String</code>.
486 * @param lnum the <code>long</code> to convert and append
487 * @return this <code>StringBuilder</code>
488 * @see String#valueOf(long)
490 public StringBuilder
append(long lnum
)
492 return append(Long
.toString(lnum
, 10));
496 * Append the <code>String</code> value of the argument to this
497 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
498 * to <code>String</code>.
500 * @param fnum the <code>float</code> to convert and append
501 * @return this <code>StringBuilder</code>
502 * @see String#valueOf(float)
504 public StringBuilder
append(float fnum
)
506 return append(Float
.toString(fnum
));
510 * Append the <code>String</code> value of the argument to this
511 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
512 * to <code>String</code>.
514 * @param dnum the <code>double</code> to convert and append
515 * @return this <code>StringBuilder</code>
516 * @see String#valueOf(double)
518 public StringBuilder
append(double dnum
)
520 return append(Double
.toString(dnum
));
524 * Delete characters from this <code>StringBuilder</code>.
525 * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is
526 * harmless for end to be larger than length().
528 * @param start the first character to delete
529 * @param end the index after the last character to delete
530 * @return this <code>StringBuilder</code>
531 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
533 public StringBuilder
delete(int start
, int end
)
535 if (start
< 0 || start
> count
|| start
> end
)
536 throw new StringIndexOutOfBoundsException(start
);
539 // This will unshare if required.
540 ensureCapacity(count
);
541 if (count
- end
!= 0)
542 System
.arraycopy(value
, end
, value
, start
, count
- end
);
543 count
-= end
- start
;
548 * Delete a character from this <code>StringBuilder</code>.
550 * @param index the index of the character to delete
551 * @return this <code>StringBuilder</code>
552 * @throws StringIndexOutOfBoundsException if index is out of bounds
554 public StringBuilder
deleteCharAt(int index
)
556 return delete(index
, index
+ 1);
560 * Replace characters between index <code>start</code> (inclusive) and
561 * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code>
562 * is larger than the size of this StringBuilder, all characters after
563 * <code>start</code> are replaced.
565 * @param start the beginning index of characters to delete (inclusive)
566 * @param end the ending index of characters to delete (exclusive)
567 * @param str the new <code>String</code> to insert
568 * @return this <code>StringBuilder</code>
569 * @throws StringIndexOutOfBoundsException if start or end are out of bounds
570 * @throws NullPointerException if str is null
572 public StringBuilder
replace(int start
, int end
, String str
)
574 if (start
< 0 || start
> count
|| start
> end
)
575 throw new StringIndexOutOfBoundsException(start
);
578 // Calculate the difference in 'count' after the replace.
579 int delta
= len
- (end
> count ? count
: end
) + start
;
580 ensureCapacity(count
+ delta
);
582 if (delta
!= 0 && end
< count
)
583 System
.arraycopy(value
, end
, value
, end
+ delta
, count
- end
);
585 str
.getChars(0, len
, value
, start
);
591 * Creates a substring of this StringBuilder, starting at a specified index
592 * and ending at the end of this StringBuilder.
594 * @param beginIndex index to start substring (base 0)
595 * @return new String which is a substring of this StringBuilder
596 * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds
597 * @see #substring(int, int)
599 public String
substring(int beginIndex
)
601 return substring(beginIndex
, count
);
605 * Creates a substring of this StringBuilder, starting at a specified index
606 * and ending at one character before a specified index. This is implemented
607 * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy
608 * the CharSequence interface.
610 * @param beginIndex index to start at (inclusive, base 0)
611 * @param endIndex index to end at (exclusive)
612 * @return new String which is a substring of this StringBuilder
613 * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of
615 * @see #substring(int, int)
617 public CharSequence
subSequence(int beginIndex
, int endIndex
)
619 return substring(beginIndex
, endIndex
);
623 * Creates a substring of this StringBuilder, starting at a specified index
624 * and ending at one character before a specified index.
626 * @param beginIndex index to start at (inclusive, base 0)
627 * @param endIndex index to end at (exclusive)
628 * @return new String which is a substring of this StringBuilder
629 * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out
632 public String
substring(int beginIndex
, int endIndex
)
634 int len
= endIndex
- beginIndex
;
635 if (beginIndex
< 0 || endIndex
> count
|| endIndex
< beginIndex
)
636 throw new StringIndexOutOfBoundsException();
639 return new String(value
, beginIndex
, len
);
643 * Insert a subarray of the <code>char[]</code> argument into this
644 * <code>StringBuilder</code>.
646 * @param offset the place to insert in this buffer
647 * @param str the <code>char[]</code> to insert
648 * @param str_offset the index in <code>str</code> to start inserting from
649 * @param len the number of characters to insert
650 * @return this <code>StringBuilder</code>
651 * @throws NullPointerException if <code>str</code> is <code>null</code>
652 * @throws StringIndexOutOfBoundsException if any index is out of bounds
654 public StringBuilder
insert(int offset
,
655 char[] str
, int str_offset
, int len
)
657 if (offset
< 0 || offset
> count
|| len
< 0
658 || str_offset
< 0 || str_offset
> str
.length
- len
)
659 throw new StringIndexOutOfBoundsException();
660 ensureCapacity(count
+ len
);
661 System
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
662 System
.arraycopy(str
, str_offset
, value
, offset
, len
);
668 * Insert the <code>String</code> value of the argument into this
669 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
670 * to <code>String</code>.
672 * @param offset the place to insert in this buffer
673 * @param obj the <code>Object</code> to convert and insert
674 * @return this <code>StringBuilder</code>
675 * @exception StringIndexOutOfBoundsException if offset is out of bounds
676 * @see String#valueOf(Object)
678 public StringBuilder
insert(int offset
, Object obj
)
680 return insert(offset
, obj
== null ?
"null" : obj
.toString());
684 * Insert the <code>String</code> argument into this
685 * <code>StringBuilder</code>. If str is null, the String "null" is used
688 * @param offset the place to insert in this buffer
689 * @param str the <code>String</code> to insert
690 * @return this <code>StringBuilder</code>
691 * @throws StringIndexOutOfBoundsException if offset is out of bounds
693 public StringBuilder
insert(int offset
, String str
)
695 if (offset
< 0 || offset
> count
)
696 throw new StringIndexOutOfBoundsException(offset
);
700 ensureCapacity(count
+ len
);
701 System
.arraycopy(value
, offset
, value
, offset
+ len
, count
- offset
);
702 str
.getChars(0, len
, value
, offset
);
708 * Insert the <code>char[]</code> argument into this
709 * <code>StringBuilder</code>.
711 * @param offset the place to insert in this buffer
712 * @param data the <code>char[]</code> to insert
713 * @return this <code>StringBuilder</code>
714 * @throws NullPointerException if <code>data</code> is <code>null</code>
715 * @throws StringIndexOutOfBoundsException if offset is out of bounds
716 * @see #insert(int, char[], int, int)
718 public StringBuilder
insert(int offset
, char[] data
)
720 return insert(offset
, data
, 0, data
.length
);
724 * Insert the <code>String</code> value of the argument into this
725 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
726 * to <code>String</code>.
728 * @param offset the place to insert in this buffer
729 * @param bool the <code>boolean</code> to convert and insert
730 * @return this <code>StringBuilder</code>
731 * @throws StringIndexOutOfBoundsException if offset is out of bounds
732 * @see String#valueOf(boolean)
734 public StringBuilder
insert(int offset
, boolean bool
)
736 return insert(offset
, bool ?
"true" : "false");
740 * Insert the <code>char</code> argument into this <code>StringBuilder</code>.
742 * @param offset the place to insert in this buffer
743 * @param ch the <code>char</code> to insert
744 * @return this <code>StringBuilder</code>
745 * @throws StringIndexOutOfBoundsException if offset is out of bounds
747 public StringBuilder
insert(int offset
, char ch
)
749 if (offset
< 0 || offset
> count
)
750 throw new StringIndexOutOfBoundsException(offset
);
751 ensureCapacity(count
+ 1);
752 System
.arraycopy(value
, offset
, value
, offset
+ 1, count
- offset
);
759 * Insert the <code>String</code> value of the argument into this
760 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
761 * to <code>String</code>.
763 * @param offset the place to insert in this buffer
764 * @param inum the <code>int</code> to convert and insert
765 * @return this <code>StringBuilder</code>
766 * @throws StringIndexOutOfBoundsException if offset is out of bounds
767 * @see String#valueOf(int)
769 public StringBuilder
insert(int offset
, int inum
)
771 return insert(offset
, String
.valueOf(inum
));
775 * Insert the <code>String</code> value of the argument into this
776 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
777 * to <code>String</code>.
779 * @param offset the place to insert in this buffer
780 * @param lnum the <code>long</code> to convert and insert
781 * @return this <code>StringBuilder</code>
782 * @throws StringIndexOutOfBoundsException if offset is out of bounds
783 * @see String#valueOf(long)
785 public StringBuilder
insert(int offset
, long lnum
)
787 return insert(offset
, Long
.toString(lnum
, 10));
791 * Insert the <code>String</code> value of the argument into this
792 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
793 * to <code>String</code>.
795 * @param offset the place to insert in this buffer
796 * @param fnum the <code>float</code> to convert and insert
797 * @return this <code>StringBuilder</code>
798 * @throws StringIndexOutOfBoundsException if offset is out of bounds
799 * @see String#valueOf(float)
801 public StringBuilder
insert(int offset
, float fnum
)
803 return insert(offset
, Float
.toString(fnum
));
807 * Insert the <code>String</code> value of the argument into this
808 * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert
809 * to <code>String</code>.
811 * @param offset the place to insert in this buffer
812 * @param dnum the <code>double</code> to convert and insert
813 * @return this <code>StringBuilder</code>
814 * @throws StringIndexOutOfBoundsException if offset is out of bounds
815 * @see String#valueOf(double)
817 public StringBuilder
insert(int offset
, double dnum
)
819 return insert(offset
, Double
.toString(dnum
));
823 * Finds the first instance of a substring in this StringBuilder.
825 * @param str String to find
826 * @return location (base 0) of the String, or -1 if not found
827 * @throws NullPointerException if str is null
828 * @see #indexOf(String, int)
830 public int indexOf(String str
)
832 return indexOf(str
, 0);
836 * Finds the first instance of a String in this StringBuilder, starting at
837 * a given index. If starting index is less than 0, the search starts at
838 * the beginning of this String. If the starting index is greater than the
839 * length of this String, or the substring is not found, -1 is returned.
841 * @param str String to find
842 * @param fromIndex index to start the search
843 * @return location (base 0) of the String, or -1 if not found
844 * @throws NullPointerException if str is null
846 public int indexOf(String str
, int fromIndex
)
850 int limit
= count
- str
.count
;
851 for ( ; fromIndex
<= limit
; fromIndex
++)
852 if (regionMatches(fromIndex
, str
))
858 * Finds the last instance of a substring in this StringBuilder.
860 * @param str String to find
861 * @return location (base 0) of the String, or -1 if not found
862 * @throws NullPointerException if str is null
863 * @see #lastIndexOf(String, int)
865 public int lastIndexOf(String str
)
867 return lastIndexOf(str
, count
- str
.count
);
871 * Finds the last instance of a String in this StringBuilder, starting at a
872 * given index. If starting index is greater than the maximum valid index,
873 * then the search begins at the end of this String. If the starting index
874 * is less than zero, or the substring is not found, -1 is returned.
876 * @param str String to find
877 * @param fromIndex index to start the search
878 * @return location (base 0) of the String, or -1 if not found
879 * @throws NullPointerException if str is null
881 public int lastIndexOf(String str
, int fromIndex
)
883 fromIndex
= Math
.min(fromIndex
, count
- str
.count
);
884 for ( ; fromIndex
>= 0; fromIndex
--)
885 if (regionMatches(fromIndex
, str
))
891 * Reverse the characters in this StringBuilder. The same sequence of
892 * characters exists, but in the reverse index ordering.
894 * @return this <code>StringBuilder</code>
896 public StringBuilder
reverse()
898 // Call ensureCapacity to enforce copy-on-write.
899 ensureCapacity(count
);
900 for (int i
= count
>> 1, j
= count
- i
; --i
>= 0; ++j
)
910 * Convert this <code>StringBuilder</code> to a <code>String</code>. The
911 * String is composed of the characters currently in this StringBuilder. Note
912 * that the result is a copy, and that future modifications to this buffer
913 * do not affect the String.
915 * @return the characters in this StringBuilder
917 public String
toString()
919 return new String(this);
923 * Predicate which determines if a substring of this matches another String
924 * starting at a specified offset for each String and continuing for a
925 * specified length. This is more efficient than creating a String to call
928 * @param toffset index to start comparison at for this String
929 * @param other non-null String to compare to region of this
930 * @return true if regions match, false otherwise
931 * @see #indexOf(String, int)
932 * @see #lastIndexOf(String, int)
933 * @see String#regionMatches(boolean, int, String, int, int)
935 // GCJ LOCAL: Native to access String internals properly.
936 private native boolean regionMatches(int toffset
, String other
);