View Javadoc
1   /*
2    * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle in the LICENSE file that accompanied this code.
10   *
11   * This code is distributed in the hope that it will be useful, but WITHOUT
12   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   * version 2 for more details (a copy is included in the LICENSE file that
15   * accompanied this code).
16   *
17   * You should have received a copy of the GNU General Public License version
18   * 2 along with this work; if not, write to the Free Software Foundation,
19   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20   *
21   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  package java.lang;
27  
28  import sun.misc.FloatingDecimal;
29  import java.util.Arrays;
30  
31  /**
32   * A mutable sequence of characters.
33   * <p>
34   * Implements a modifiable string. At any point in time it contains some
35   * particular sequence of characters, but the length and content of the
36   * sequence can be changed through certain method calls.
37   *
38   * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
39   * or method in this class will cause a {@link NullPointerException} to be
40   * thrown.
41   *
42   * @author      Michael McCloskey
43   * @author      Martin Buchholz
44   * @author      Ulf Zibis
45   * @since       1.5
46   */
47  abstract class AbstractStringBuilder implements Appendable, CharSequence {
48      /**
49       * The value is used for character storage.
50       */
51      char[] value;
52  
53      /**
54       * The count is the number of characters used.
55       */
56      int count;
57  
58      /**
59       * This no-arg constructor is necessary for serialization of subclasses.
60       */
61      AbstractStringBuilder() {
62      }
63  
64      /**
65       * Creates an AbstractStringBuilder of the specified capacity.
66       */
67      AbstractStringBuilder(int capacity) {
68          value = new char[capacity];
69      }
70  
71      /**
72       * Returns the length (character count).
73       *
74       * @return  the length of the sequence of characters currently
75       *          represented by this object
76       */
77      @Override
78      public int length() {
79          return count;
80      }
81  
82      /**
83       * Returns the current capacity. The capacity is the amount of storage
84       * available for newly inserted characters, beyond which an allocation
85       * will occur.
86       *
87       * @return  the current capacity
88       */
89      public int capacity() {
90          return value.length;
91      }
92  
93      /**
94       * Ensures that the capacity is at least equal to the specified minimum.
95       * If the current capacity is less than the argument, then a new internal
96       * array is allocated with greater capacity. The new capacity is the
97       * larger of:
98       * <ul>
99       * <li>The {@code minimumCapacity} argument.
100      * <li>Twice the old capacity, plus {@code 2}.
101      * </ul>
102      * If the {@code minimumCapacity} argument is nonpositive, this
103      * method takes no action and simply returns.
104      * Note that subsequent operations on this object can reduce the
105      * actual capacity below that requested here.
106      *
107      * @param   minimumCapacity   the minimum desired capacity.
108      */
109     public void ensureCapacity(int minimumCapacity) {
110         if (minimumCapacity > 0)
111             ensureCapacityInternal(minimumCapacity);
112     }
113 
114     /**
115      * This method has the same contract as ensureCapacity, but is
116      * never synchronized.
117      */
118     private void ensureCapacityInternal(int minimumCapacity) {
119         // overflow-conscious code
120         if (minimumCapacity - value.length > 0)
121             expandCapacity(minimumCapacity);
122     }
123 
124     /**
125      * This implements the expansion semantics of ensureCapacity with no
126      * size check or synchronization.
127      */
128     void expandCapacity(int minimumCapacity) {
129         int newCapacity = value.length * 2 + 2;
130         if (newCapacity - minimumCapacity < 0)
131             newCapacity = minimumCapacity;
132         if (newCapacity < 0) {
133             if (minimumCapacity < 0) // overflow
134                 throw new OutOfMemoryError();
135             newCapacity = Integer.MAX_VALUE;
136         }
137         value = Arrays.copyOf(value, newCapacity);
138     }
139 
140     /**
141      * Attempts to reduce storage used for the character sequence.
142      * If the buffer is larger than necessary to hold its current sequence of
143      * characters, then it may be resized to become more space efficient.
144      * Calling this method may, but is not required to, affect the value
145      * returned by a subsequent call to the {@link #capacity()} method.
146      */
147     public void trimToSize() {
148         if (count < value.length) {
149             value = Arrays.copyOf(value, count);
150         }
151     }
152 
153     /**
154      * Sets the length of the character sequence.
155      * The sequence is changed to a new character sequence
156      * whose length is specified by the argument. For every nonnegative
157      * index <i>k</i> less than {@code newLength}, the character at
158      * index <i>k</i> in the new character sequence is the same as the
159      * character at index <i>k</i> in the old sequence if <i>k</i> is less
160      * than the length of the old character sequence; otherwise, it is the
161      * null character {@code '\u005Cu0000'}.
162      *
163      * In other words, if the {@code newLength} argument is less than
164      * the current length, the length is changed to the specified length.
165      * <p>
166      * If the {@code newLength} argument is greater than or equal
167      * to the current length, sufficient null characters
168      * ({@code '\u005Cu0000'}) are appended so that
169      * length becomes the {@code newLength} argument.
170      * <p>
171      * The {@code newLength} argument must be greater than or equal
172      * to {@code 0}.
173      *
174      * @param      newLength   the new length
175      * @throws     IndexOutOfBoundsException  if the
176      *               {@code newLength} argument is negative.
177      */
178     public void setLength(int newLength) {
179         if (newLength < 0)
180             throw new StringIndexOutOfBoundsException(newLength);
181         ensureCapacityInternal(newLength);
182 
183         if (count < newLength) {
184             Arrays.fill(value, count, newLength, '\0');
185         }
186 
187         count = newLength;
188     }
189 
190     /**
191      * Returns the {@code char} value in this sequence at the specified index.
192      * The first {@code char} value is at index {@code 0}, the next at index
193      * {@code 1}, and so on, as in array indexing.
194      * <p>
195      * The index argument must be greater than or equal to
196      * {@code 0}, and less than the length of this sequence.
197      *
198      * <p>If the {@code char} value specified by the index is a
199      * <a href="Character.html#unicode">surrogate</a>, the surrogate
200      * value is returned.
201      *
202      * @param      index   the index of the desired {@code char} value.
203      * @return     the {@code char} value at the specified index.
204      * @throws     IndexOutOfBoundsException  if {@code index} is
205      *             negative or greater than or equal to {@code length()}.
206      */
207     @Override
208     public char charAt(int index) {
209         if ((index < 0) || (index >= count))
210             throw new StringIndexOutOfBoundsException(index);
211         return value[index];
212     }
213 
214     /**
215      * Returns the character (Unicode code point) at the specified
216      * index. The index refers to {@code char} values
217      * (Unicode code units) and ranges from {@code 0} to
218      * {@link #length()}{@code  - 1}.
219      *
220      * <p> If the {@code char} value specified at the given index
221      * is in the high-surrogate range, the following index is less
222      * than the length of this sequence, and the
223      * {@code char} value at the following index is in the
224      * low-surrogate range, then the supplementary code point
225      * corresponding to this surrogate pair is returned. Otherwise,
226      * the {@code char} value at the given index is returned.
227      *
228      * @param      index the index to the {@code char} values
229      * @return     the code point value of the character at the
230      *             {@code index}
231      * @exception  IndexOutOfBoundsException  if the {@code index}
232      *             argument is negative or not less than the length of this
233      *             sequence.
234      */
235     public int codePointAt(int index) {
236         if ((index < 0) || (index >= count)) {
237             throw new StringIndexOutOfBoundsException(index);
238         }
239         return Character.codePointAtImpl(value, index, count);
240     }
241 
242     /**
243      * Returns the character (Unicode code point) before the specified
244      * index. The index refers to {@code char} values
245      * (Unicode code units) and ranges from {@code 1} to {@link
246      * #length()}.
247      *
248      * <p> If the {@code char} value at {@code (index - 1)}
249      * is in the low-surrogate range, {@code (index - 2)} is not
250      * negative, and the {@code char} value at {@code (index -
251      * 2)} is in the high-surrogate range, then the
252      * supplementary code point value of the surrogate pair is
253      * returned. If the {@code char} value at {@code index -
254      * 1} is an unpaired low-surrogate or a high-surrogate, the
255      * surrogate value is returned.
256      *
257      * @param     index the index following the code point that should be returned
258      * @return    the Unicode code point value before the given index.
259      * @exception IndexOutOfBoundsException if the {@code index}
260      *            argument is less than 1 or greater than the length
261      *            of this sequence.
262      */
263     public int codePointBefore(int index) {
264         int i = index - 1;
265         if ((i < 0) || (i >= count)) {
266             throw new StringIndexOutOfBoundsException(index);
267         }
268         return Character.codePointBeforeImpl(value, index, 0);
269     }
270 
271     /**
272      * Returns the number of Unicode code points in the specified text
273      * range of this sequence. The text range begins at the specified
274      * {@code beginIndex} and extends to the {@code char} at
275      * index {@code endIndex - 1}. Thus the length (in
276      * {@code char}s) of the text range is
277      * {@code endIndex-beginIndex}. Unpaired surrogates within
278      * this sequence count as one code point each.
279      *
280      * @param beginIndex the index to the first {@code char} of
281      * the text range.
282      * @param endIndex the index after the last {@code char} of
283      * the text range.
284      * @return the number of Unicode code points in the specified text
285      * range
286      * @exception IndexOutOfBoundsException if the
287      * {@code beginIndex} is negative, or {@code endIndex}
288      * is larger than the length of this sequence, or
289      * {@code beginIndex} is larger than {@code endIndex}.
290      */
291     public int codePointCount(int beginIndex, int endIndex) {
292         if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) {
293             throw new IndexOutOfBoundsException();
294         }
295         return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex);
296     }
297 
298     /**
299      * Returns the index within this sequence that is offset from the
300      * given {@code index} by {@code codePointOffset} code
301      * points. Unpaired surrogates within the text range given by
302      * {@code index} and {@code codePointOffset} count as
303      * one code point each.
304      *
305      * @param index the index to be offset
306      * @param codePointOffset the offset in code points
307      * @return the index within this sequence
308      * @exception IndexOutOfBoundsException if {@code index}
309      *   is negative or larger then the length of this sequence,
310      *   or if {@code codePointOffset} is positive and the subsequence
311      *   starting with {@code index} has fewer than
312      *   {@code codePointOffset} code points,
313      *   or if {@code codePointOffset} is negative and the subsequence
314      *   before {@code index} has fewer than the absolute value of
315      *   {@code codePointOffset} code points.
316      */
317     public int offsetByCodePoints(int index, int codePointOffset) {
318         if (index < 0 || index > count) {
319             throw new IndexOutOfBoundsException();
320         }
321         return Character.offsetByCodePointsImpl(value, 0, count,
322                                                 index, codePointOffset);
323     }
324 
325     /**
326      * Characters are copied from this sequence into the
327      * destination character array {@code dst}. The first character to
328      * be copied is at index {@code srcBegin}; the last character to
329      * be copied is at index {@code srcEnd-1}. The total number of
330      * characters to be copied is {@code srcEnd-srcBegin}. The
331      * characters are copied into the subarray of {@code dst} starting
332      * at index {@code dstBegin} and ending at index:
333      * <pre>{@code
334      * dstbegin + (srcEnd-srcBegin) - 1
335      * }</pre>
336      *
337      * @param      srcBegin   start copying at this offset.
338      * @param      srcEnd     stop copying at this offset.
339      * @param      dst        the array to copy the data into.
340      * @param      dstBegin   offset into {@code dst}.
341      * @throws     IndexOutOfBoundsException  if any of the following is true:
342      *             <ul>
343      *             <li>{@code srcBegin} is negative
344      *             <li>{@code dstBegin} is negative
345      *             <li>the {@code srcBegin} argument is greater than
346      *             the {@code srcEnd} argument.
347      *             <li>{@code srcEnd} is greater than
348      *             {@code this.length()}.
349      *             <li>{@code dstBegin+srcEnd-srcBegin} is greater than
350      *             {@code dst.length}
351      *             </ul>
352      */
353     public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
354     {
355         if (srcBegin < 0)
356             throw new StringIndexOutOfBoundsException(srcBegin);
357         if ((srcEnd < 0) || (srcEnd > count))
358             throw new StringIndexOutOfBoundsException(srcEnd);
359         if (srcBegin > srcEnd)
360             throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
361         System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
362     }
363 
364     /**
365      * The character at the specified index is set to {@code ch}. This
366      * sequence is altered to represent a new character sequence that is
367      * identical to the old character sequence, except that it contains the
368      * character {@code ch} at position {@code index}.
369      * <p>
370      * The index argument must be greater than or equal to
371      * {@code 0}, and less than the length of this sequence.
372      *
373      * @param      index   the index of the character to modify.
374      * @param      ch      the new character.
375      * @throws     IndexOutOfBoundsException  if {@code index} is
376      *             negative or greater than or equal to {@code length()}.
377      */
378     public void setCharAt(int index, char ch) {
379         if ((index < 0) || (index >= count))
380             throw new StringIndexOutOfBoundsException(index);
381         value[index] = ch;
382     }
383 
384     /**
385      * Appends the string representation of the {@code Object} argument.
386      * <p>
387      * The overall effect is exactly as if the argument were converted
388      * to a string by the method {@link String#valueOf(Object)},
389      * and the characters of that string were then
390      * {@link #append(String) appended} to this character sequence.
391      *
392      * @param   obj   an {@code Object}.
393      * @return  a reference to this object.
394      */
395     public AbstractStringBuilder append(Object obj) {
396         return append(String.valueOf(obj));
397     }
398 
399     /**
400      * Appends the specified string to this character sequence.
401      * <p>
402      * The characters of the {@code String} argument are appended, in
403      * order, increasing the length of this sequence by the length of the
404      * argument. If {@code str} is {@code null}, then the four
405      * characters {@code "null"} are appended.
406      * <p>
407      * Let <i>n</i> be the length of this character sequence just prior to
408      * execution of the {@code append} method. Then the character at
409      * index <i>k</i> in the new character sequence is equal to the character
410      * at index <i>k</i> in the old character sequence, if <i>k</i> is less
411      * than <i>n</i>; otherwise, it is equal to the character at index
412      * <i>k-n</i> in the argument {@code str}.
413      *
414      * @param   str   a string.
415      * @return  a reference to this object.
416      */
417     public AbstractStringBuilder append(String str) {
418         if (str == null)
419             return appendNull();
420         int len = str.length();
421         ensureCapacityInternal(count + len);
422         str.getChars(0, len, value, count);
423         count += len;
424         return this;
425     }
426 
427     // Documentation in subclasses because of synchro difference
428     public AbstractStringBuilder append(StringBuffer sb) {
429         if (sb == null)
430             return appendNull();
431         int len = sb.length();
432         ensureCapacityInternal(count + len);
433         sb.getChars(0, len, value, count);
434         count += len;
435         return this;
436     }
437 
438     /**
439      * @since 1.8
440      */
441     AbstractStringBuilder append(AbstractStringBuilder asb) {
442         if (asb == null)
443             return appendNull();
444         int len = asb.length();
445         ensureCapacityInternal(count + len);
446         asb.getChars(0, len, value, count);
447         count += len;
448         return this;
449     }
450 
451     // Documentation in subclasses because of synchro difference
452     @Override
453     public AbstractStringBuilder append(CharSequence s) {
454         if (s == null)
455             return appendNull();
456         if (s instanceof String)
457             return this.append((String)s);
458         if (s instanceof AbstractStringBuilder)
459             return this.append((AbstractStringBuilder)s);
460 
461         return this.append(s, 0, s.length());
462     }
463 
464     private AbstractStringBuilder appendNull() {
465         int c = count;
466         ensureCapacityInternal(c + 4);
467         final char[] value = this.value;
468         value[c++] = 'n';
469         value[c++] = 'u';
470         value[c++] = 'l';
471         value[c++] = 'l';
472         count = c;
473         return this;
474     }
475 
476     /**
477      * Appends a subsequence of the specified {@code CharSequence} to this
478      * sequence.
479      * <p>
480      * Characters of the argument {@code s}, starting at
481      * index {@code start}, are appended, in order, to the contents of
482      * this sequence up to the (exclusive) index {@code end}. The length
483      * of this sequence is increased by the value of {@code end - start}.
484      * <p>
485      * Let <i>n</i> be the length of this character sequence just prior to
486      * execution of the {@code append} method. Then the character at
487      * index <i>k</i> in this character sequence becomes equal to the
488      * character at index <i>k</i> in this sequence, if <i>k</i> is less than
489      * <i>n</i>; otherwise, it is equal to the character at index
490      * <i>k+start-n</i> in the argument {@code s}.
491      * <p>
492      * If {@code s} is {@code null}, then this method appends
493      * characters as if the s parameter was a sequence containing the four
494      * characters {@code "null"}.
495      *
496      * @param   s the sequence to append.
497      * @param   start   the starting index of the subsequence to be appended.
498      * @param   end     the end index of the subsequence to be appended.
499      * @return  a reference to this object.
500      * @throws     IndexOutOfBoundsException if
501      *             {@code start} is negative, or
502      *             {@code start} is greater than {@code end} or
503      *             {@code end} is greater than {@code s.length()}
504      */
505     @Override
506     public AbstractStringBuilder append(CharSequence s, int start, int end) {
507         if (s == null)
508             s = "null";
509         if ((start < 0) || (start > end) || (end > s.length()))
510             throw new IndexOutOfBoundsException(
511                 "start " + start + ", end " + end + ", s.length() "
512                 + s.length());
513         int len = end - start;
514         ensureCapacityInternal(count + len);
515         for (int i = start, j = count; i < end; i++, j++)
516             value[j] = s.charAt(i);
517         count += len;
518         return this;
519     }
520 
521     /**
522      * Appends the string representation of the {@code char} array
523      * argument to this sequence.
524      * <p>
525      * The characters of the array argument are appended, in order, to
526      * the contents of this sequence. The length of this sequence
527      * increases by the length of the argument.
528      * <p>
529      * The overall effect is exactly as if the argument were converted
530      * to a string by the method {@link String#valueOf(char[])},
531      * and the characters of that string were then
532      * {@link #append(String) appended} to this character sequence.
533      *
534      * @param   str   the characters to be appended.
535      * @return  a reference to this object.
536      */
537     public AbstractStringBuilder append(char[] str) {
538         int len = str.length;
539         ensureCapacityInternal(count + len);
540         System.arraycopy(str, 0, value, count, len);
541         count += len;
542         return this;
543     }
544 
545     /**
546      * Appends the string representation of a subarray of the
547      * {@code char} array argument to this sequence.
548      * <p>
549      * Characters of the {@code char} array {@code str}, starting at
550      * index {@code offset}, are appended, in order, to the contents
551      * of this sequence. The length of this sequence increases
552      * by the value of {@code len}.
553      * <p>
554      * The overall effect is exactly as if the arguments were converted
555      * to a string by the method {@link String#valueOf(char[],int,int)},
556      * and the characters of that string were then
557      * {@link #append(String) appended} to this character sequence.
558      *
559      * @param   str      the characters to be appended.
560      * @param   offset   the index of the first {@code char} to append.
561      * @param   len      the number of {@code char}s to append.
562      * @return  a reference to this object.
563      * @throws IndexOutOfBoundsException
564      *         if {@code offset < 0} or {@code len < 0}
565      *         or {@code offset+len > str.length}
566      */
567     public AbstractStringBuilder append(char str[], int offset, int len) {
568         if (len > 0)                // let arraycopy report AIOOBE for len < 0
569             ensureCapacityInternal(count + len);
570         System.arraycopy(str, offset, value, count, len);
571         count += len;
572         return this;
573     }
574 
575     /**
576      * Appends the string representation of the {@code boolean}
577      * argument to the sequence.
578      * <p>
579      * The overall effect is exactly as if the argument were converted
580      * to a string by the method {@link String#valueOf(boolean)},
581      * and the characters of that string were then
582      * {@link #append(String) appended} to this character sequence.
583      *
584      * @param   b   a {@code boolean}.
585      * @return  a reference to this object.
586      */
587     public AbstractStringBuilder append(boolean b) {
588         if (b) {
589             ensureCapacityInternal(count + 4);
590             value[count++] = 't';
591             value[count++] = 'r';
592             value[count++] = 'u';
593             value[count++] = 'e';
594         } else {
595             ensureCapacityInternal(count + 5);
596             value[count++] = 'f';
597             value[count++] = 'a';
598             value[count++] = 'l';
599             value[count++] = 's';
600             value[count++] = 'e';
601         }
602         return this;
603     }
604 
605     /**
606      * Appends the string representation of the {@code char}
607      * argument to this sequence.
608      * <p>
609      * The argument is appended to the contents of this sequence.
610      * The length of this sequence increases by {@code 1}.
611      * <p>
612      * The overall effect is exactly as if the argument were converted
613      * to a string by the method {@link String#valueOf(char)},
614      * and the character in that string were then
615      * {@link #append(String) appended} to this character sequence.
616      *
617      * @param   c   a {@code char}.
618      * @return  a reference to this object.
619      */
620     @Override
621     public AbstractStringBuilder append(char c) {
622         ensureCapacityInternal(count + 1);
623         value[count++] = c;
624         return this;
625     }
626 
627     /**
628      * Appends the string representation of the {@code int}
629      * argument to this sequence.
630      * <p>
631      * The overall effect is exactly as if the argument were converted
632      * to a string by the method {@link String#valueOf(int)},
633      * and the characters of that string were then
634      * {@link #append(String) appended} to this character sequence.
635      *
636      * @param   i   an {@code int}.
637      * @return  a reference to this object.
638      */
639     public AbstractStringBuilder append(int i) {
640         if (i == Integer.MIN_VALUE) {
641             append("-2147483648");
642             return this;
643         }
644         int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
645                                      : Integer.stringSize(i);
646         int spaceNeeded = count + appendedLength;
647         ensureCapacityInternal(spaceNeeded);
648         Integer.getChars(i, spaceNeeded, value);
649         count = spaceNeeded;
650         return this;
651     }
652 
653     /**
654      * Appends the string representation of the {@code long}
655      * argument to this sequence.
656      * <p>
657      * The overall effect is exactly as if the argument were converted
658      * to a string by the method {@link String#valueOf(long)},
659      * and the characters of that string were then
660      * {@link #append(String) appended} to this character sequence.
661      *
662      * @param   l   a {@code long}.
663      * @return  a reference to this object.
664      */
665     public AbstractStringBuilder append(long l) {
666         if (l == Long.MIN_VALUE) {
667             append("-9223372036854775808");
668             return this;
669         }
670         int appendedLength = (l < 0) ? Long.stringSize(-l) + 1
671                                      : Long.stringSize(l);
672         int spaceNeeded = count + appendedLength;
673         ensureCapacityInternal(spaceNeeded);
674         Long.getChars(l, spaceNeeded, value);
675         count = spaceNeeded;
676         return this;
677     }
678 
679     /**
680      * Appends the string representation of the {@code float}
681      * argument to this sequence.
682      * <p>
683      * The overall effect is exactly as if the argument were converted
684      * to a string by the method {@link String#valueOf(float)},
685      * and the characters of that string were then
686      * {@link #append(String) appended} to this character sequence.
687      *
688      * @param   f   a {@code float}.
689      * @return  a reference to this object.
690      */
691     public AbstractStringBuilder append(float f) {
692         FloatingDecimal.appendTo(f,this);
693         return this;
694     }
695 
696     /**
697      * Appends the string representation of the {@code double}
698      * argument to this sequence.
699      * <p>
700      * The overall effect is exactly as if the argument were converted
701      * to a string by the method {@link String#valueOf(double)},
702      * and the characters of that string were then
703      * {@link #append(String) appended} to this character sequence.
704      *
705      * @param   d   a {@code double}.
706      * @return  a reference to this object.
707      */
708     public AbstractStringBuilder append(double d) {
709         FloatingDecimal.appendTo(d,this);
710         return this;
711     }
712 
713     /**
714      * Removes the characters in a substring of this sequence.
715      * The substring begins at the specified {@code start} and extends to
716      * the character at index {@code end - 1} or to the end of the
717      * sequence if no such character exists. If
718      * {@code start} is equal to {@code end}, no changes are made.
719      *
720      * @param      start  The beginning index, inclusive.
721      * @param      end    The ending index, exclusive.
722      * @return     This object.
723      * @throws     StringIndexOutOfBoundsException  if {@code start}
724      *             is negative, greater than {@code length()}, or
725      *             greater than {@code end}.
726      */
727     public AbstractStringBuilder delete(int start, int end) {
728         if (start < 0)
729             throw new StringIndexOutOfBoundsException(start);
730         if (end > count)
731             end = count;
732         if (start > end)
733             throw new StringIndexOutOfBoundsException();
734         int len = end - start;
735         if (len > 0) {
736             System.arraycopy(value, start+len, value, start, count-end);
737             count -= len;
738         }
739         return this;
740     }
741 
742     /**
743      * Appends the string representation of the {@code codePoint}
744      * argument to this sequence.
745      *
746      * <p> The argument is appended to the contents of this sequence.
747      * The length of this sequence increases by
748      * {@link Character#charCount(int) Character.charCount(codePoint)}.
749      *
750      * <p> The overall effect is exactly as if the argument were
751      * converted to a {@code char} array by the method
752      * {@link Character#toChars(int)} and the character in that array
753      * were then {@link #append(char[]) appended} to this character
754      * sequence.
755      *
756      * @param   codePoint   a Unicode code point
757      * @return  a reference to this object.
758      * @exception IllegalArgumentException if the specified
759      * {@code codePoint} isn't a valid Unicode code point
760      */
761     public AbstractStringBuilder appendCodePoint(int codePoint) {
762         final int count = this.count;
763 
764         if (Character.isBmpCodePoint(codePoint)) {
765             ensureCapacityInternal(count + 1);
766             value[count] = (char) codePoint;
767             this.count = count + 1;
768         } else if (Character.isValidCodePoint(codePoint)) {
769             ensureCapacityInternal(count + 2);
770             Character.toSurrogates(codePoint, value, count);
771             this.count = count + 2;
772         } else {
773             throw new IllegalArgumentException();
774         }
775         return this;
776     }
777 
778     /**
779      * Removes the {@code char} at the specified position in this
780      * sequence. This sequence is shortened by one {@code char}.
781      *
782      * <p>Note: If the character at the given index is a supplementary
783      * character, this method does not remove the entire character. If
784      * correct handling of supplementary characters is required,
785      * determine the number of {@code char}s to remove by calling
786      * {@code Character.charCount(thisSequence.codePointAt(index))},
787      * where {@code thisSequence} is this sequence.
788      *
789      * @param       index  Index of {@code char} to remove
790      * @return      This object.
791      * @throws      StringIndexOutOfBoundsException  if the {@code index}
792      *              is negative or greater than or equal to
793      *              {@code length()}.
794      */
795     public AbstractStringBuilder deleteCharAt(int index) {
796         if ((index < 0) || (index >= count))
797             throw new StringIndexOutOfBoundsException(index);
798         System.arraycopy(value, index+1, value, index, count-index-1);
799         count--;
800         return this;
801     }
802 
803     /**
804      * Replaces the characters in a substring of this sequence
805      * with characters in the specified {@code String}. The substring
806      * begins at the specified {@code start} and extends to the character
807      * at index {@code end - 1} or to the end of the
808      * sequence if no such character exists. First the
809      * characters in the substring are removed and then the specified
810      * {@code String} is inserted at {@code start}. (This
811      * sequence will be lengthened to accommodate the
812      * specified String if necessary.)
813      *
814      * @param      start    The beginning index, inclusive.
815      * @param      end      The ending index, exclusive.
816      * @param      str   String that will replace previous contents.
817      * @return     This object.
818      * @throws     StringIndexOutOfBoundsException  if {@code start}
819      *             is negative, greater than {@code length()}, or
820      *             greater than {@code end}.
821      */
822     public AbstractStringBuilder replace(int start, int end, String str) {
823         if (start < 0)
824             throw new StringIndexOutOfBoundsException(start);
825         if (start > count)
826             throw new StringIndexOutOfBoundsException("start > length()");
827         if (start > end)
828             throw new StringIndexOutOfBoundsException("start > end");
829 
830         if (end > count)
831             end = count;
832         int len = str.length();
833         int newCount = count + len - (end - start);
834         ensureCapacityInternal(newCount);
835 
836         System.arraycopy(value, end, value, start + len, count - end);
837         str.getChars(value, start);
838         count = newCount;
839         return this;
840     }
841 
842     /**
843      * Returns a new {@code String} that contains a subsequence of
844      * characters currently contained in this character sequence. The
845      * substring begins at the specified index and extends to the end of
846      * this sequence.
847      *
848      * @param      start    The beginning index, inclusive.
849      * @return     The new string.
850      * @throws     StringIndexOutOfBoundsException  if {@code start} is
851      *             less than zero, or greater than the length of this object.
852      */
853     public String substring(int start) {
854         return substring(start, count);
855     }
856 
857     /**
858      * Returns a new character sequence that is a subsequence of this sequence.
859      *
860      * <p> An invocation of this method of the form
861      *
862      * <pre>{@code
863      * sb.subSequence(begin,&nbsp;end)}</pre>
864      *
865      * behaves in exactly the same way as the invocation
866      *
867      * <pre>{@code
868      * sb.substring(begin,&nbsp;end)}</pre>
869      *
870      * This method is provided so that this class can
871      * implement the {@link CharSequence} interface.
872      *
873      * @param      start   the start index, inclusive.
874      * @param      end     the end index, exclusive.
875      * @return     the specified subsequence.
876      *
877      * @throws  IndexOutOfBoundsException
878      *          if {@code start} or {@code end} are negative,
879      *          if {@code end} is greater than {@code length()},
880      *          or if {@code start} is greater than {@code end}
881      * @spec JSR-51
882      */
883     @Override
884     public CharSequence subSequence(int start, int end) {
885         return substring(start, end);
886     }
887 
888     /**
889      * Returns a new {@code String} that contains a subsequence of
890      * characters currently contained in this sequence. The
891      * substring begins at the specified {@code start} and
892      * extends to the character at index {@code end - 1}.
893      *
894      * @param      start    The beginning index, inclusive.
895      * @param      end      The ending index, exclusive.
896      * @return     The new string.
897      * @throws     StringIndexOutOfBoundsException  if {@code start}
898      *             or {@code end} are negative or greater than
899      *             {@code length()}, or {@code start} is
900      *             greater than {@code end}.
901      */
902     public String substring(int start, int end) {
903         if (start < 0)
904             throw new StringIndexOutOfBoundsException(start);
905         if (end > count)
906             throw new StringIndexOutOfBoundsException(end);
907         if (start > end)
908             throw new StringIndexOutOfBoundsException(end - start);
909         return new String(value, start, end - start);
910     }
911 
912     /**
913      * Inserts the string representation of a subarray of the {@code str}
914      * array argument into this sequence. The subarray begins at the
915      * specified {@code offset} and extends {@code len} {@code char}s.
916      * The characters of the subarray are inserted into this sequence at
917      * the position indicated by {@code index}. The length of this
918      * sequence increases by {@code len} {@code char}s.
919      *
920      * @param      index    position at which to insert subarray.
921      * @param      str       A {@code char} array.
922      * @param      offset   the index of the first {@code char} in subarray to
923      *             be inserted.
924      * @param      len      the number of {@code char}s in the subarray to
925      *             be inserted.
926      * @return     This object
927      * @throws     StringIndexOutOfBoundsException  if {@code index}
928      *             is negative or greater than {@code length()}, or
929      *             {@code offset} or {@code len} are negative, or
930      *             {@code (offset+len)} is greater than
931      *             {@code str.length}.
932      */
933     public AbstractStringBuilder insert(int index, char[] str, int offset,
934                                         int len)
935     {
936         if ((index < 0) || (index > length()))
937             throw new StringIndexOutOfBoundsException(index);
938         if ((offset < 0) || (len < 0) || (offset > str.length - len))
939             throw new StringIndexOutOfBoundsException(
940                 "offset " + offset + ", len " + len + ", str.length "
941                 + str.length);
942         ensureCapacityInternal(count + len);
943         System.arraycopy(value, index, value, index + len, count - index);
944         System.arraycopy(str, offset, value, index, len);
945         count += len;
946         return this;
947     }
948 
949     /**
950      * Inserts the string representation of the {@code Object}
951      * argument into this character sequence.
952      * <p>
953      * The overall effect is exactly as if the second argument were
954      * converted to a string by the method {@link String#valueOf(Object)},
955      * and the characters of that string were then
956      * {@link #insert(int,String) inserted} into this character
957      * sequence at the indicated offset.
958      * <p>
959      * The {@code offset} argument must be greater than or equal to
960      * {@code 0}, and less than or equal to the {@linkplain #length() length}
961      * of this sequence.
962      *
963      * @param      offset   the offset.
964      * @param      obj      an {@code Object}.
965      * @return     a reference to this object.
966      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
967      */
968     public AbstractStringBuilder insert(int offset, Object obj) {
969         return insert(offset, String.valueOf(obj));
970     }
971 
972     /**
973      * Inserts the string into this character sequence.
974      * <p>
975      * The characters of the {@code String} argument are inserted, in
976      * order, into this sequence at the indicated offset, moving up any
977      * characters originally above that position and increasing the length
978      * of this sequence by the length of the argument. If
979      * {@code str} is {@code null}, then the four characters
980      * {@code "null"} are inserted into this sequence.
981      * <p>
982      * The character at index <i>k</i> in the new character sequence is
983      * equal to:
984      * <ul>
985      * <li>the character at index <i>k</i> in the old character sequence, if
986      * <i>k</i> is less than {@code offset}
987      * <li>the character at index <i>k</i>{@code -offset} in the
988      * argument {@code str}, if <i>k</i> is not less than
989      * {@code offset} but is less than {@code offset+str.length()}
990      * <li>the character at index <i>k</i>{@code -str.length()} in the
991      * old character sequence, if <i>k</i> is not less than
992      * {@code offset+str.length()}
993      * </ul><p>
994      * The {@code offset} argument must be greater than or equal to
995      * {@code 0}, and less than or equal to the {@linkplain #length() length}
996      * of this sequence.
997      *
998      * @param      offset   the offset.
999      * @param      str      a string.
1000      * @return     a reference to this object.
1001      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1002      */
1003     public AbstractStringBuilder insert(int offset, String str) {
1004         if ((offset < 0) || (offset > length()))
1005             throw new StringIndexOutOfBoundsException(offset);
1006         if (str == null)
1007             str = "null";
1008         int len = str.length();
1009         ensureCapacityInternal(count + len);
1010         System.arraycopy(value, offset, value, offset + len, count - offset);
1011         str.getChars(value, offset);
1012         count += len;
1013         return this;
1014     }
1015 
1016     /**
1017      * Inserts the string representation of the {@code char} array
1018      * argument into this sequence.
1019      * <p>
1020      * The characters of the array argument are inserted into the
1021      * contents of this sequence at the position indicated by
1022      * {@code offset}. The length of this sequence increases by
1023      * the length of the argument.
1024      * <p>
1025      * The overall effect is exactly as if the second argument were
1026      * converted to a string by the method {@link String#valueOf(char[])},
1027      * and the characters of that string were then
1028      * {@link #insert(int,String) inserted} into this character
1029      * sequence at the indicated offset.
1030      * <p>
1031      * The {@code offset} argument must be greater than or equal to
1032      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1033      * of this sequence.
1034      *
1035      * @param      offset   the offset.
1036      * @param      str      a character array.
1037      * @return     a reference to this object.
1038      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1039      */
1040     public AbstractStringBuilder insert(int offset, char[] str) {
1041         if ((offset < 0) || (offset > length()))
1042             throw new StringIndexOutOfBoundsException(offset);
1043         int len = str.length;
1044         ensureCapacityInternal(count + len);
1045         System.arraycopy(value, offset, value, offset + len, count - offset);
1046         System.arraycopy(str, 0, value, offset, len);
1047         count += len;
1048         return this;
1049     }
1050 
1051     /**
1052      * Inserts the specified {@code CharSequence} into this sequence.
1053      * <p>
1054      * The characters of the {@code CharSequence} argument are inserted,
1055      * in order, into this sequence at the indicated offset, moving up
1056      * any characters originally above that position and increasing the length
1057      * of this sequence by the length of the argument s.
1058      * <p>
1059      * The result of this method is exactly the same as if it were an
1060      * invocation of this object's
1061      * {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
1062      * method.
1063      *
1064      * <p>If {@code s} is {@code null}, then the four characters
1065      * {@code "null"} are inserted into this sequence.
1066      *
1067      * @param      dstOffset   the offset.
1068      * @param      s the sequence to be inserted
1069      * @return     a reference to this object.
1070      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1071      */
1072     public AbstractStringBuilder insert(int dstOffset, CharSequence s) {
1073         if (s == null)
1074             s = "null";
1075         if (s instanceof String)
1076             return this.insert(dstOffset, (String)s);
1077         return this.insert(dstOffset, s, 0, s.length());
1078     }
1079 
1080     /**
1081      * Inserts a subsequence of the specified {@code CharSequence} into
1082      * this sequence.
1083      * <p>
1084      * The subsequence of the argument {@code s} specified by
1085      * {@code start} and {@code end} are inserted,
1086      * in order, into this sequence at the specified destination offset, moving
1087      * up any characters originally above that position. The length of this
1088      * sequence is increased by {@code end - start}.
1089      * <p>
1090      * The character at index <i>k</i> in this sequence becomes equal to:
1091      * <ul>
1092      * <li>the character at index <i>k</i> in this sequence, if
1093      * <i>k</i> is less than {@code dstOffset}
1094      * <li>the character at index <i>k</i>{@code +start-dstOffset} in
1095      * the argument {@code s}, if <i>k</i> is greater than or equal to
1096      * {@code dstOffset} but is less than {@code dstOffset+end-start}
1097      * <li>the character at index <i>k</i>{@code -(end-start)} in this
1098      * sequence, if <i>k</i> is greater than or equal to
1099      * {@code dstOffset+end-start}
1100      * </ul><p>
1101      * The {@code dstOffset} argument must be greater than or equal to
1102      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1103      * of this sequence.
1104      * <p>The start argument must be nonnegative, and not greater than
1105      * {@code end}.
1106      * <p>The end argument must be greater than or equal to
1107      * {@code start}, and less than or equal to the length of s.
1108      *
1109      * <p>If {@code s} is {@code null}, then this method inserts
1110      * characters as if the s parameter was a sequence containing the four
1111      * characters {@code "null"}.
1112      *
1113      * @param      dstOffset   the offset in this sequence.
1114      * @param      s       the sequence to be inserted.
1115      * @param      start   the starting index of the subsequence to be inserted.
1116      * @param      end     the end index of the subsequence to be inserted.
1117      * @return     a reference to this object.
1118      * @throws     IndexOutOfBoundsException  if {@code dstOffset}
1119      *             is negative or greater than {@code this.length()}, or
1120      *              {@code start} or {@code end} are negative, or
1121      *              {@code start} is greater than {@code end} or
1122      *              {@code end} is greater than {@code s.length()}
1123      */
1124      public AbstractStringBuilder insert(int dstOffset, CharSequence s,
1125                                          int start, int end) {
1126         if (s == null)
1127             s = "null";
1128         if ((dstOffset < 0) || (dstOffset > this.length()))
1129             throw new IndexOutOfBoundsException("dstOffset "+dstOffset);
1130         if ((start < 0) || (end < 0) || (start > end) || (end > s.length()))
1131             throw new IndexOutOfBoundsException(
1132                 "start " + start + ", end " + end + ", s.length() "
1133                 + s.length());
1134         int len = end - start;
1135         ensureCapacityInternal(count + len);
1136         System.arraycopy(value, dstOffset, value, dstOffset + len,
1137                          count - dstOffset);
1138         for (int i=start; i<end; i++)
1139             value[dstOffset++] = s.charAt(i);
1140         count += len;
1141         return this;
1142     }
1143 
1144     /**
1145      * Inserts the string representation of the {@code boolean}
1146      * argument into this sequence.
1147      * <p>
1148      * The overall effect is exactly as if the second argument were
1149      * converted to a string by the method {@link String#valueOf(boolean)},
1150      * and the characters of that string were then
1151      * {@link #insert(int,String) inserted} into this character
1152      * sequence at the indicated offset.
1153      * <p>
1154      * The {@code offset} argument must be greater than or equal to
1155      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1156      * of this sequence.
1157      *
1158      * @param      offset   the offset.
1159      * @param      b        a {@code boolean}.
1160      * @return     a reference to this object.
1161      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1162      */
1163     public AbstractStringBuilder insert(int offset, boolean b) {
1164         return insert(offset, String.valueOf(b));
1165     }
1166 
1167     /**
1168      * Inserts the string representation of the {@code char}
1169      * argument into this sequence.
1170      * <p>
1171      * The overall effect is exactly as if the second argument were
1172      * converted to a string by the method {@link String#valueOf(char)},
1173      * and the character in that string were then
1174      * {@link #insert(int,String) inserted} into this character
1175      * sequence at the indicated offset.
1176      * <p>
1177      * The {@code offset} argument must be greater than or equal to
1178      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1179      * of this sequence.
1180      *
1181      * @param      offset   the offset.
1182      * @param      c        a {@code char}.
1183      * @return     a reference to this object.
1184      * @throws     IndexOutOfBoundsException  if the offset is invalid.
1185      */
1186     public AbstractStringBuilder insert(int offset, char c) {
1187         ensureCapacityInternal(count + 1);
1188         System.arraycopy(value, offset, value, offset + 1, count - offset);
1189         value[offset] = c;
1190         count += 1;
1191         return this;
1192     }
1193 
1194     /**
1195      * Inserts the string representation of the second {@code int}
1196      * argument into this sequence.
1197      * <p>
1198      * The overall effect is exactly as if the second argument were
1199      * converted to a string by the method {@link String#valueOf(int)},
1200      * and the characters of that string were then
1201      * {@link #insert(int,String) inserted} into this character
1202      * sequence at the indicated offset.
1203      * <p>
1204      * The {@code offset} argument must be greater than or equal to
1205      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1206      * of this sequence.
1207      *
1208      * @param      offset   the offset.
1209      * @param      i        an {@code int}.
1210      * @return     a reference to this object.
1211      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1212      */
1213     public AbstractStringBuilder insert(int offset, int i) {
1214         return insert(offset, String.valueOf(i));
1215     }
1216 
1217     /**
1218      * Inserts the string representation of the {@code long}
1219      * argument into this sequence.
1220      * <p>
1221      * The overall effect is exactly as if the second argument were
1222      * converted to a string by the method {@link String#valueOf(long)},
1223      * and the characters of that string were then
1224      * {@link #insert(int,String) inserted} into this character
1225      * sequence at the indicated offset.
1226      * <p>
1227      * The {@code offset} argument must be greater than or equal to
1228      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1229      * of this sequence.
1230      *
1231      * @param      offset   the offset.
1232      * @param      l        a {@code long}.
1233      * @return     a reference to this object.
1234      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1235      */
1236     public AbstractStringBuilder insert(int offset, long l) {
1237         return insert(offset, String.valueOf(l));
1238     }
1239 
1240     /**
1241      * Inserts the string representation of the {@code float}
1242      * argument into this sequence.
1243      * <p>
1244      * The overall effect is exactly as if the second argument were
1245      * converted to a string by the method {@link String#valueOf(float)},
1246      * and the characters of that string were then
1247      * {@link #insert(int,String) inserted} into this character
1248      * sequence at the indicated offset.
1249      * <p>
1250      * The {@code offset} argument must be greater than or equal to
1251      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1252      * of this sequence.
1253      *
1254      * @param      offset   the offset.
1255      * @param      f        a {@code float}.
1256      * @return     a reference to this object.
1257      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1258      */
1259     public AbstractStringBuilder insert(int offset, float f) {
1260         return insert(offset, String.valueOf(f));
1261     }
1262 
1263     /**
1264      * Inserts the string representation of the {@code double}
1265      * argument into this sequence.
1266      * <p>
1267      * The overall effect is exactly as if the second argument were
1268      * converted to a string by the method {@link String#valueOf(double)},
1269      * and the characters of that string were then
1270      * {@link #insert(int,String) inserted} into this character
1271      * sequence at the indicated offset.
1272      * <p>
1273      * The {@code offset} argument must be greater than or equal to
1274      * {@code 0}, and less than or equal to the {@linkplain #length() length}
1275      * of this sequence.
1276      *
1277      * @param      offset   the offset.
1278      * @param      d        a {@code double}.
1279      * @return     a reference to this object.
1280      * @throws     StringIndexOutOfBoundsException  if the offset is invalid.
1281      */
1282     public AbstractStringBuilder insert(int offset, double d) {
1283         return insert(offset, String.valueOf(d));
1284     }
1285 
1286     /**
1287      * Returns the index within this string of the first occurrence of the
1288      * specified substring. The integer returned is the smallest value
1289      * <i>k</i> such that:
1290      * <pre>{@code
1291      * this.toString().startsWith(str, <i>k</i>)
1292      * }</pre>
1293      * is {@code true}.
1294      *
1295      * @param   str   any string.
1296      * @return  if the string argument occurs as a substring within this
1297      *          object, then the index of the first character of the first
1298      *          such substring is returned; if it does not occur as a
1299      *          substring, {@code -1} is returned.
1300      */
1301     public int indexOf(String str) {
1302         return indexOf(str, 0);
1303     }
1304 
1305     /**
1306      * Returns the index within this string of the first occurrence of the
1307      * specified substring, starting at the specified index.  The integer
1308      * returned is the smallest value {@code k} for which:
1309      * <pre>{@code
1310      *     k >= Math.min(fromIndex, this.length()) &&
1311      *                   this.toString().startsWith(str, k)
1312      * }</pre>
1313      * If no such value of <i>k</i> exists, then -1 is returned.
1314      *
1315      * @param   str         the substring for which to search.
1316      * @param   fromIndex   the index from which to start the search.
1317      * @return  the index within this string of the first occurrence of the
1318      *          specified substring, starting at the specified index.
1319      */
1320     public int indexOf(String str, int fromIndex) {
1321         return String.indexOf(value, 0, count, str, fromIndex);
1322     }
1323 
1324     /**
1325      * Returns the index within this string of the rightmost occurrence
1326      * of the specified substring.  The rightmost empty string "" is
1327      * considered to occur at the index value {@code this.length()}.
1328      * The returned index is the largest value <i>k</i> such that
1329      * <pre>{@code
1330      * this.toString().startsWith(str, k)
1331      * }</pre>
1332      * is true.
1333      *
1334      * @param   str   the substring to search for.
1335      * @return  if the string argument occurs one or more times as a substring
1336      *          within this object, then the index of the first character of
1337      *          the last such substring is returned. If it does not occur as
1338      *          a substring, {@code -1} is returned.
1339      */
1340     public int lastIndexOf(String str) {
1341         return lastIndexOf(str, count);
1342     }
1343 
1344     /**
1345      * Returns the index within this string of the last occurrence of the
1346      * specified substring. The integer returned is the largest value <i>k</i>
1347      * such that:
1348      * <pre>{@code
1349      *     k <= Math.min(fromIndex, this.length()) &&
1350      *                   this.toString().startsWith(str, k)
1351      * }</pre>
1352      * If no such value of <i>k</i> exists, then -1 is returned.
1353      *
1354      * @param   str         the substring to search for.
1355      * @param   fromIndex   the index to start the search from.
1356      * @return  the index within this sequence of the last occurrence of the
1357      *          specified substring.
1358      */
1359     public int lastIndexOf(String str, int fromIndex) {
1360         return String.lastIndexOf(value, 0, count, str, fromIndex);
1361     }
1362 
1363     /**
1364      * Causes this character sequence to be replaced by the reverse of
1365      * the sequence. If there are any surrogate pairs included in the
1366      * sequence, these are treated as single characters for the
1367      * reverse operation. Thus, the order of the high-low surrogates
1368      * is never reversed.
1369      *
1370      * Let <i>n</i> be the character length of this character sequence
1371      * (not the length in {@code char} values) just prior to
1372      * execution of the {@code reverse} method. Then the
1373      * character at index <i>k</i> in the new character sequence is
1374      * equal to the character at index <i>n-k-1</i> in the old
1375      * character sequence.
1376      *
1377      * <p>Note that the reverse operation may result in producing
1378      * surrogate pairs that were unpaired low-surrogates and
1379      * high-surrogates before the operation. For example, reversing
1380      * "\u005CuDC00\u005CuD800" produces "\u005CuD800\u005CuDC00" which is
1381      * a valid surrogate pair.
1382      *
1383      * @return  a reference to this object.
1384      */
1385     public AbstractStringBuilder reverse() {
1386         boolean hasSurrogates = false;
1387         int n = count - 1;
1388         for (int j = (n-1) >> 1; j >= 0; j--) {
1389             int k = n - j;
1390             char cj = value[j];
1391             char ck = value[k];
1392             value[j] = ck;
1393             value[k] = cj;
1394             if (Character.isSurrogate(cj) ||
1395                 Character.isSurrogate(ck)) {
1396                 hasSurrogates = true;
1397             }
1398         }
1399         if (hasSurrogates) {
1400             reverseAllValidSurrogatePairs();
1401         }
1402         return this;
1403     }
1404 
1405     /** Outlined helper method for reverse() */
1406     private void reverseAllValidSurrogatePairs() {
1407         for (int i = 0; i < count - 1; i++) {
1408             char c2 = value[i];
1409             if (Character.isLowSurrogate(c2)) {
1410                 char c1 = value[i + 1];
1411                 if (Character.isHighSurrogate(c1)) {
1412                     value[i++] = c1;
1413                     value[i] = c2;
1414                 }
1415             }
1416         }
1417     }
1418 
1419     /**
1420      * Returns a string representing the data in this sequence.
1421      * A new {@code String} object is allocated and initialized to
1422      * contain the character sequence currently represented by this
1423      * object. This {@code String} is then returned. Subsequent
1424      * changes to this sequence do not affect the contents of the
1425      * {@code String}.
1426      *
1427      * @return  a string representation of this sequence of characters.
1428      */
1429     @Override
1430     public abstract String toString();
1431 
1432     /**
1433      * Needed by {@code String} for the contentEquals method.
1434      */
1435     final char[] getValue() {
1436         return value;
1437     }
1438 
1439 }