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 jdk.internal.math.FloatingDecimal;
29 import java.util.Arrays;
30 import java.util.Spliterator;
31 import java.util.stream.IntStream;
32 import java.util.stream.StreamSupport;
33
34 import static java.lang.String.COMPACT_STRINGS;
35 import static java.lang.String.UTF16;
36 import static java.lang.String.LATIN1;
37 import static java.lang.String.checkIndex;
38 import static java.lang.String.checkOffset;
39
40 /**
41 * A mutable sequence of characters.
42 * <p>
43 * Implements a modifiable string. At any point in time it contains some
44 * particular sequence of characters, but the length and content of the
45 * sequence can be changed through certain method calls.
46 *
47 * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
48 * or method in this class will cause a {@link NullPointerException} to be
49 * thrown.
50 *
51 * @author Michael McCloskey
52 * @author Martin Buchholz
53 * @author Ulf Zibis
54 * @since 1.5
55 */
56 abstract class AbstractStringBuilder implements Appendable, CharSequence {
57 /**
58 * The value is used for character storage.
290 * index. The index refers to {@code char} values
291 * (Unicode code units) and ranges from {@code 0} to
292 * {@link #length()}{@code - 1}.
293 *
294 * <p> If the {@code char} value specified at the given index
295 * is in the high-surrogate range, the following index is less
296 * than the length of this sequence, and the
297 * {@code char} value at the following index is in the
298 * low-surrogate range, then the supplementary code point
299 * corresponding to this surrogate pair is returned. Otherwise,
300 * the {@code char} value at the given index is returned.
301 *
302 * @param index the index to the {@code char} values
303 * @return the code point value of the character at the
304 * {@code index}
305 * @exception IndexOutOfBoundsException if the {@code index}
306 * argument is negative or not less than the length of this
307 * sequence.
308 */
309 public int codePointAt(int index) {
310 checkIndex(index, count);
311 if (isLatin1()) {
312 return value[index] & 0xff;
313 }
314 return StringUTF16.codePointAtSB(value, index, count);
315 }
316
317 /**
318 * Returns the character (Unicode code point) before the specified
319 * index. The index refers to {@code char} values
320 * (Unicode code units) and ranges from {@code 1} to {@link
321 * #length()}.
322 *
323 * <p> If the {@code char} value at {@code (index - 1)}
324 * is in the low-surrogate range, {@code (index - 2)} is not
325 * negative, and the {@code char} value at {@code (index -
326 * 2)} is in the high-surrogate range, then the
327 * supplementary code point value of the surrogate pair is
328 * returned. If the {@code char} value at {@code index -
329 * 1} is an unpaired low-surrogate or a high-surrogate, the
543 }
544 if (s instanceof String) {
545 return this.append((String)s);
546 }
547 if (s instanceof AbstractStringBuilder) {
548 return this.append((AbstractStringBuilder)s);
549 }
550 return this.append(s, 0, s.length());
551 }
552
553 private AbstractStringBuilder appendNull() {
554 ensureCapacityInternal(count + 4);
555 int count = this.count;
556 byte[] val = this.value;
557 if (isLatin1()) {
558 val[count++] = 'n';
559 val[count++] = 'u';
560 val[count++] = 'l';
561 val[count++] = 'l';
562 } else {
563 checkOffset(count + 4, val.length >> 1);
564 StringUTF16.putChar(val, count++, 'n');
565 StringUTF16.putChar(val, count++, 'u');
566 StringUTF16.putChar(val, count++, 'l');
567 StringUTF16.putChar(val, count++, 'l');
568 }
569 this.count = count;
570 return this;
571 }
572
573 /**
574 * Appends a subsequence of the specified {@code CharSequence} to this
575 * sequence.
576 * <p>
577 * Characters of the argument {@code s}, starting at
578 * index {@code start}, are appended, in order, to the contents of
579 * this sequence up to the (exclusive) index {@code end}. The length
580 * of this sequence is increased by the value of {@code end - start}.
581 * <p>
582 * Let <i>n</i> be the length of this character sequence just prior to
583 * execution of the {@code append} method. Then the character at
678 */
679 public AbstractStringBuilder append(boolean b) {
680 ensureCapacityInternal(count + (b ? 4 : 5));
681 int count = this.count;
682 byte[] val = this.value;
683 if (isLatin1()) {
684 if (b) {
685 val[count++] = 't';
686 val[count++] = 'r';
687 val[count++] = 'u';
688 val[count++] = 'e';
689 } else {
690 val[count++] = 'f';
691 val[count++] = 'a';
692 val[count++] = 'l';
693 val[count++] = 's';
694 val[count++] = 'e';
695 }
696 } else {
697 if (b) {
698 checkOffset(count + 4, val.length >> 1);
699 StringUTF16.putChar(val, count++, 't');
700 StringUTF16.putChar(val, count++, 'r');
701 StringUTF16.putChar(val, count++, 'u');
702 StringUTF16.putChar(val, count++, 'e');
703 } else {
704 checkOffset(count + 5, val.length >> 1);
705 StringUTF16.putChar(val, count++, 'f');
706 StringUTF16.putChar(val, count++, 'a');
707 StringUTF16.putChar(val, count++, 'l');
708 StringUTF16.putChar(val, count++, 's');
709 StringUTF16.putChar(val, count++, 'e');
710 }
711 }
712 this.count = count;
713 return this;
714 }
715
716 /**
717 * Appends the string representation of the {@code char}
718 * argument to this sequence.
719 * <p>
720 * The argument is appended to the contents of this sequence.
721 * The length of this sequence increases by {@code 1}.
722 * <p>
723 * The overall effect is exactly as if the argument were converted
724 * to a string by the method {@link String#valueOf(char)},
738 inflate();
739 }
740 StringUTF16.putCharSB(value, count++, c);
741 }
742 return this;
743 }
744
745 /**
746 * Appends the string representation of the {@code int}
747 * argument to this sequence.
748 * <p>
749 * The overall effect is exactly as if the argument were converted
750 * to a string by the method {@link String#valueOf(int)},
751 * and the characters of that string were then
752 * {@link #append(String) appended} to this character sequence.
753 *
754 * @param i an {@code int}.
755 * @return a reference to this object.
756 */
757 public AbstractStringBuilder append(int i) {
758 int spaceNeeded = count + Integer.stringSize(i);
759 ensureCapacityInternal(spaceNeeded);
760 if (isLatin1()) {
761 Integer.getChars(i, spaceNeeded, value);
762 } else {
763 byte[] val = this.value;
764 checkOffset(spaceNeeded, val.length >> 1);
765 Integer.getCharsUTF16(i, spaceNeeded, val);
766 }
767 count = spaceNeeded;
768 return this;
769 }
770
771 /**
772 * Appends the string representation of the {@code long}
773 * argument to this sequence.
774 * <p>
775 * The overall effect is exactly as if the argument were converted
776 * to a string by the method {@link String#valueOf(long)},
777 * and the characters of that string were then
778 * {@link #append(String) appended} to this character sequence.
779 *
780 * @param l a {@code long}.
781 * @return a reference to this object.
782 */
783 public AbstractStringBuilder append(long l) {
784 int spaceNeeded = count + Long.stringSize(l);
785 ensureCapacityInternal(spaceNeeded);
786 if (isLatin1()) {
787 Long.getChars(l, spaceNeeded, value);
788 } else {
789 byte[] val = this.value;
790 checkOffset(spaceNeeded, val.length >> 1);
791 Long.getCharsUTF16(l, spaceNeeded, val);
792 }
793 count = spaceNeeded;
794 return this;
795 }
796
797 /**
798 * Appends the string representation of the {@code float}
799 * argument to this sequence.
800 * <p>
801 * The overall effect is exactly as if the argument were converted
802 * to a string by the method {@link String#valueOf(float)},
803 * and the characters of that string were then
804 * {@link #append(String) appended} to this character sequence.
805 *
806 * @param f a {@code float}.
807 * @return a reference to this object.
808 */
809 public AbstractStringBuilder append(float f) {
810 FloatingDecimal.appendTo(f,this);
811 return this;
812 }
813
826 public AbstractStringBuilder append(double d) {
827 FloatingDecimal.appendTo(d,this);
828 return this;
829 }
830
831 /**
832 * Removes the characters in a substring of this sequence.
833 * The substring begins at the specified {@code start} and extends to
834 * the character at index {@code end - 1} or to the end of the
835 * sequence if no such character exists. If
836 * {@code start} is equal to {@code end}, no changes are made.
837 *
838 * @param start The beginning index, inclusive.
839 * @param end The ending index, exclusive.
840 * @return This object.
841 * @throws StringIndexOutOfBoundsException if {@code start}
842 * is negative, greater than {@code length()}, or
843 * greater than {@code end}.
844 */
845 public AbstractStringBuilder delete(int start, int end) {
846 if (end > count) {
847 end = count;
848 }
849 checkRangeSIOOBE(start, end, count);
850 int len = end - start;
851 if (len > 0) {
852 shift(end, -len);
853 count -= len;
854 }
855 return this;
856 }
857
858 /**
859 * Appends the string representation of the {@code codePoint}
860 * argument to this sequence.
861 *
862 * <p> The argument is appended to the contents of this sequence.
863 * The length of this sequence increases by
864 * {@link Character#charCount(int) Character.charCount(codePoint)}.
865 *
866 * <p> The overall effect is exactly as if the argument were
867 * converted to a {@code char} array by the method
868 * {@link Character#toChars(int)} and the character in that array
869 * were then {@link #append(char[]) appended} to this character
870 * sequence.
871 *
872 * @param codePoint a Unicode code point
873 * @return a reference to this object.
908 /**
909 * Replaces the characters in a substring of this sequence
910 * with characters in the specified {@code String}. The substring
911 * begins at the specified {@code start} and extends to the character
912 * at index {@code end - 1} or to the end of the
913 * sequence if no such character exists. First the
914 * characters in the substring are removed and then the specified
915 * {@code String} is inserted at {@code start}. (This
916 * sequence will be lengthened to accommodate the
917 * specified String if necessary.)
918 *
919 * @param start The beginning index, inclusive.
920 * @param end The ending index, exclusive.
921 * @param str String that will replace previous contents.
922 * @return This object.
923 * @throws StringIndexOutOfBoundsException if {@code start}
924 * is negative, greater than {@code length()}, or
925 * greater than {@code end}.
926 */
927 public AbstractStringBuilder replace(int start, int end, String str) {
928 if (end > count) {
929 end = count;
930 }
931 checkRangeSIOOBE(start, end, count);
932 int len = str.length();
933 int newCount = count + len - (end - start);
934 ensureCapacityInternal(newCount);
935 shift(end, newCount - count);
936 count = newCount;
937 putStringAt(start, str);
938 return this;
939 }
940
941 /**
942 * Returns a new {@code String} that contains a subsequence of
943 * characters currently contained in this character sequence. The
944 * substring begins at the specified index and extends to the end of
945 * this sequence.
946 *
947 * @param start The beginning index, inclusive.
948 * @return The new string.
949 * @throws StringIndexOutOfBoundsException if {@code start} is
950 * less than zero, or greater than the length of this object.
951 */
952 public String substring(int start) {
953 return substring(start, count);
954 }
955
956 /**
1405 }
1406
1407 /**
1408 * Returns the index within this string of the first occurrence of the
1409 * specified substring, starting at the specified index.
1410 *
1411 * <p>The returned index is the smallest value {@code k} for which:
1412 * <pre>{@code
1413 * k >= Math.min(fromIndex, this.length()) &&
1414 * this.toString().startsWith(str, k)
1415 * }</pre>
1416 * If no such value of {@code k} exists, then {@code -1} is returned.
1417 *
1418 * @param str the substring to search for.
1419 * @param fromIndex the index from which to start the search.
1420 * @return the index of the first occurrence of the specified substring,
1421 * starting at the specified index,
1422 * or {@code -1} if there is no such occurrence.
1423 */
1424 public int indexOf(String str, int fromIndex) {
1425 return String.indexOf(value, coder, count, str, fromIndex);
1426 }
1427
1428 /**
1429 * Returns the index within this string of the last occurrence of the
1430 * specified substring. The last occurrence of the empty string "" is
1431 * considered to occur at the index value {@code this.length()}.
1432 *
1433 * <p>The returned index is the largest value {@code k} for which:
1434 * <pre>{@code
1435 * this.toString().startsWith(str, k)
1436 * }</pre>
1437 * If no such value of {@code k} exists, then {@code -1} is returned.
1438 *
1439 * @param str the substring to search for.
1440 * @return the index of the last occurrence of the specified substring,
1441 * or {@code -1} if there is no such occurrence.
1442 */
1443 public int lastIndexOf(String str) {
1444 return lastIndexOf(str, count);
1445 }
1446
1447 /**
1448 * Returns the index within this string of the last occurrence of the
1449 * specified substring, searching backward starting at the specified index.
1450 *
1451 * <p>The returned index is the largest value {@code k} for which:
1452 * <pre>{@code
1453 * k <= Math.min(fromIndex, this.length()) &&
1454 * this.toString().startsWith(str, k)
1455 * }</pre>
1456 * If no such value of {@code k} exists, then {@code -1} is returned.
1457 *
1458 * @param str the substring to search for.
1459 * @param fromIndex the index to start the search from.
1460 * @return the index of the last occurrence of the specified substring,
1461 * searching backward from the specified index,
1462 * or {@code -1} if there is no such occurrence.
1463 */
1464 public int lastIndexOf(String str, int fromIndex) {
1465 return String.lastIndexOf(value, coder, count, str, fromIndex);
1466 }
1467
1468 /**
1469 * Causes this character sequence to be replaced by the reverse of
1470 * the sequence. If there are any surrogate pairs included in the
1471 * sequence, these are treated as single characters for the
1472 * reverse operation. Thus, the order of the high-low surrogates
1473 * is never reversed.
1474 *
1475 * Let <i>n</i> be the character length of this character sequence
1476 * (not the length in {@code char} values) just prior to
1477 * execution of the {@code reverse} method. Then the
1478 * character at index <i>k</i> in the new character sequence is
1479 * equal to the character at index <i>n-k-1</i> in the old
1480 * character sequence.
1481 *
1482 * <p>Note that the reverse operation may result in producing
1483 * surrogate pairs that were unpaired low-surrogates and
1484 * high-surrogates before the operation. For example, reversing
|
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 jdk.internal.math.FloatingDecimal;
29 import java.util.Arrays;
30 import java.util.Spliterator;
31 import java.util.stream.IntStream;
32 import java.util.stream.StreamSupport;
33
34 import static java.lang.String.COMPACT_STRINGS;
35 import static java.lang.String.UTF16;
36 import static java.lang.String.LATIN1;
37 import static java.lang.String.checkIndex;
38 import static java.lang.String.checkOffset;
39 import static java.lang.String.checkBoundsBeginEnd;
40
41 /**
42 * A mutable sequence of characters.
43 * <p>
44 * Implements a modifiable string. At any point in time it contains some
45 * particular sequence of characters, but the length and content of the
46 * sequence can be changed through certain method calls.
47 *
48 * <p>Unless otherwise noted, passing a {@code null} argument to a constructor
49 * or method in this class will cause a {@link NullPointerException} to be
50 * thrown.
51 *
52 * @author Michael McCloskey
53 * @author Martin Buchholz
54 * @author Ulf Zibis
55 * @since 1.5
56 */
57 abstract class AbstractStringBuilder implements Appendable, CharSequence {
58 /**
59 * The value is used for character storage.
291 * index. The index refers to {@code char} values
292 * (Unicode code units) and ranges from {@code 0} to
293 * {@link #length()}{@code - 1}.
294 *
295 * <p> If the {@code char} value specified at the given index
296 * is in the high-surrogate range, the following index is less
297 * than the length of this sequence, and the
298 * {@code char} value at the following index is in the
299 * low-surrogate range, then the supplementary code point
300 * corresponding to this surrogate pair is returned. Otherwise,
301 * the {@code char} value at the given index is returned.
302 *
303 * @param index the index to the {@code char} values
304 * @return the code point value of the character at the
305 * {@code index}
306 * @exception IndexOutOfBoundsException if the {@code index}
307 * argument is negative or not less than the length of this
308 * sequence.
309 */
310 public int codePointAt(int index) {
311 int count = this.count;
312 byte[] value = this.value;
313 checkIndex(index, count);
314 if (isLatin1()) {
315 return value[index] & 0xff;
316 }
317 return StringUTF16.codePointAtSB(value, index, count);
318 }
319
320 /**
321 * Returns the character (Unicode code point) before the specified
322 * index. The index refers to {@code char} values
323 * (Unicode code units) and ranges from {@code 1} to {@link
324 * #length()}.
325 *
326 * <p> If the {@code char} value at {@code (index - 1)}
327 * is in the low-surrogate range, {@code (index - 2)} is not
328 * negative, and the {@code char} value at {@code (index -
329 * 2)} is in the high-surrogate range, then the
330 * supplementary code point value of the surrogate pair is
331 * returned. If the {@code char} value at {@code index -
332 * 1} is an unpaired low-surrogate or a high-surrogate, the
546 }
547 if (s instanceof String) {
548 return this.append((String)s);
549 }
550 if (s instanceof AbstractStringBuilder) {
551 return this.append((AbstractStringBuilder)s);
552 }
553 return this.append(s, 0, s.length());
554 }
555
556 private AbstractStringBuilder appendNull() {
557 ensureCapacityInternal(count + 4);
558 int count = this.count;
559 byte[] val = this.value;
560 if (isLatin1()) {
561 val[count++] = 'n';
562 val[count++] = 'u';
563 val[count++] = 'l';
564 val[count++] = 'l';
565 } else {
566 checkBoundsBeginEnd(count, count + 4, val.length >> 1);
567 StringUTF16.putChar(val, count++, 'n');
568 StringUTF16.putChar(val, count++, 'u');
569 StringUTF16.putChar(val, count++, 'l');
570 StringUTF16.putChar(val, count++, 'l');
571 }
572 this.count = count;
573 return this;
574 }
575
576 /**
577 * Appends a subsequence of the specified {@code CharSequence} to this
578 * sequence.
579 * <p>
580 * Characters of the argument {@code s}, starting at
581 * index {@code start}, are appended, in order, to the contents of
582 * this sequence up to the (exclusive) index {@code end}. The length
583 * of this sequence is increased by the value of {@code end - start}.
584 * <p>
585 * Let <i>n</i> be the length of this character sequence just prior to
586 * execution of the {@code append} method. Then the character at
681 */
682 public AbstractStringBuilder append(boolean b) {
683 ensureCapacityInternal(count + (b ? 4 : 5));
684 int count = this.count;
685 byte[] val = this.value;
686 if (isLatin1()) {
687 if (b) {
688 val[count++] = 't';
689 val[count++] = 'r';
690 val[count++] = 'u';
691 val[count++] = 'e';
692 } else {
693 val[count++] = 'f';
694 val[count++] = 'a';
695 val[count++] = 'l';
696 val[count++] = 's';
697 val[count++] = 'e';
698 }
699 } else {
700 if (b) {
701 checkBoundsBeginEnd(count, count + 4, val.length >> 1);
702 StringUTF16.putChar(val, count++, 't');
703 StringUTF16.putChar(val, count++, 'r');
704 StringUTF16.putChar(val, count++, 'u');
705 StringUTF16.putChar(val, count++, 'e');
706 } else {
707 checkBoundsBeginEnd(count, count + 5, val.length >> 1);
708 StringUTF16.putChar(val, count++, 'f');
709 StringUTF16.putChar(val, count++, 'a');
710 StringUTF16.putChar(val, count++, 'l');
711 StringUTF16.putChar(val, count++, 's');
712 StringUTF16.putChar(val, count++, 'e');
713 }
714 }
715 this.count = count;
716 return this;
717 }
718
719 /**
720 * Appends the string representation of the {@code char}
721 * argument to this sequence.
722 * <p>
723 * The argument is appended to the contents of this sequence.
724 * The length of this sequence increases by {@code 1}.
725 * <p>
726 * The overall effect is exactly as if the argument were converted
727 * to a string by the method {@link String#valueOf(char)},
741 inflate();
742 }
743 StringUTF16.putCharSB(value, count++, c);
744 }
745 return this;
746 }
747
748 /**
749 * Appends the string representation of the {@code int}
750 * argument to this sequence.
751 * <p>
752 * The overall effect is exactly as if the argument were converted
753 * to a string by the method {@link String#valueOf(int)},
754 * and the characters of that string were then
755 * {@link #append(String) appended} to this character sequence.
756 *
757 * @param i an {@code int}.
758 * @return a reference to this object.
759 */
760 public AbstractStringBuilder append(int i) {
761 int count = this.count;
762 int spaceNeeded = count + Integer.stringSize(i);
763 ensureCapacityInternal(spaceNeeded);
764 if (isLatin1()) {
765 Integer.getChars(i, spaceNeeded, value);
766 } else {
767 byte[] val = this.value;
768 checkBoundsBeginEnd(count, spaceNeeded, val.length >> 1);
769 Integer.getCharsUTF16(i, spaceNeeded, val);
770 }
771 this.count = spaceNeeded;
772 return this;
773 }
774
775 /**
776 * Appends the string representation of the {@code long}
777 * argument to this sequence.
778 * <p>
779 * The overall effect is exactly as if the argument were converted
780 * to a string by the method {@link String#valueOf(long)},
781 * and the characters of that string were then
782 * {@link #append(String) appended} to this character sequence.
783 *
784 * @param l a {@code long}.
785 * @return a reference to this object.
786 */
787 public AbstractStringBuilder append(long l) {
788 int count = this.count;
789 int spaceNeeded = count + Long.stringSize(l);
790 ensureCapacityInternal(spaceNeeded);
791 if (isLatin1()) {
792 Long.getChars(l, spaceNeeded, value);
793 } else {
794 byte[] val = this.value;
795 checkBoundsBeginEnd(count, spaceNeeded, val.length >> 1);
796 Long.getCharsUTF16(l, spaceNeeded, val);
797 }
798 this.count = spaceNeeded;
799 return this;
800 }
801
802 /**
803 * Appends the string representation of the {@code float}
804 * argument to this sequence.
805 * <p>
806 * The overall effect is exactly as if the argument were converted
807 * to a string by the method {@link String#valueOf(float)},
808 * and the characters of that string were then
809 * {@link #append(String) appended} to this character sequence.
810 *
811 * @param f a {@code float}.
812 * @return a reference to this object.
813 */
814 public AbstractStringBuilder append(float f) {
815 FloatingDecimal.appendTo(f,this);
816 return this;
817 }
818
831 public AbstractStringBuilder append(double d) {
832 FloatingDecimal.appendTo(d,this);
833 return this;
834 }
835
836 /**
837 * Removes the characters in a substring of this sequence.
838 * The substring begins at the specified {@code start} and extends to
839 * the character at index {@code end - 1} or to the end of the
840 * sequence if no such character exists. If
841 * {@code start} is equal to {@code end}, no changes are made.
842 *
843 * @param start The beginning index, inclusive.
844 * @param end The ending index, exclusive.
845 * @return This object.
846 * @throws StringIndexOutOfBoundsException if {@code start}
847 * is negative, greater than {@code length()}, or
848 * greater than {@code end}.
849 */
850 public AbstractStringBuilder delete(int start, int end) {
851 int count = this.count;
852 if (end > count) {
853 end = count;
854 }
855 checkRangeSIOOBE(start, end, count);
856 int len = end - start;
857 if (len > 0) {
858 shift(end, -len);
859 this.count = count - len;
860 }
861 return this;
862 }
863
864 /**
865 * Appends the string representation of the {@code codePoint}
866 * argument to this sequence.
867 *
868 * <p> The argument is appended to the contents of this sequence.
869 * The length of this sequence increases by
870 * {@link Character#charCount(int) Character.charCount(codePoint)}.
871 *
872 * <p> The overall effect is exactly as if the argument were
873 * converted to a {@code char} array by the method
874 * {@link Character#toChars(int)} and the character in that array
875 * were then {@link #append(char[]) appended} to this character
876 * sequence.
877 *
878 * @param codePoint a Unicode code point
879 * @return a reference to this object.
914 /**
915 * Replaces the characters in a substring of this sequence
916 * with characters in the specified {@code String}. The substring
917 * begins at the specified {@code start} and extends to the character
918 * at index {@code end - 1} or to the end of the
919 * sequence if no such character exists. First the
920 * characters in the substring are removed and then the specified
921 * {@code String} is inserted at {@code start}. (This
922 * sequence will be lengthened to accommodate the
923 * specified String if necessary.)
924 *
925 * @param start The beginning index, inclusive.
926 * @param end The ending index, exclusive.
927 * @param str String that will replace previous contents.
928 * @return This object.
929 * @throws StringIndexOutOfBoundsException if {@code start}
930 * is negative, greater than {@code length()}, or
931 * greater than {@code end}.
932 */
933 public AbstractStringBuilder replace(int start, int end, String str) {
934 int count = this.count;
935 if (end > count) {
936 end = count;
937 }
938 checkRangeSIOOBE(start, end, count);
939 int len = str.length();
940 int newCount = count + len - (end - start);
941 ensureCapacityInternal(newCount);
942 shift(end, newCount - count);
943 this.count = newCount;
944 putStringAt(start, str);
945 return this;
946 }
947
948 /**
949 * Returns a new {@code String} that contains a subsequence of
950 * characters currently contained in this character sequence. The
951 * substring begins at the specified index and extends to the end of
952 * this sequence.
953 *
954 * @param start The beginning index, inclusive.
955 * @return The new string.
956 * @throws StringIndexOutOfBoundsException if {@code start} is
957 * less than zero, or greater than the length of this object.
958 */
959 public String substring(int start) {
960 return substring(start, count);
961 }
962
963 /**
1412 }
1413
1414 /**
1415 * Returns the index within this string of the first occurrence of the
1416 * specified substring, starting at the specified index.
1417 *
1418 * <p>The returned index is the smallest value {@code k} for which:
1419 * <pre>{@code
1420 * k >= Math.min(fromIndex, this.length()) &&
1421 * this.toString().startsWith(str, k)
1422 * }</pre>
1423 * If no such value of {@code k} exists, then {@code -1} is returned.
1424 *
1425 * @param str the substring to search for.
1426 * @param fromIndex the index from which to start the search.
1427 * @return the index of the first occurrence of the specified substring,
1428 * starting at the specified index,
1429 * or {@code -1} if there is no such occurrence.
1430 */
1431 public int indexOf(String str, int fromIndex) {
1432 byte[] value = this.value;
1433 int count = this.count;
1434 byte coder = this.coder;
1435 checkOffset(count, value.length >> coder);
1436 return String.indexOf(value, coder, count, str, fromIndex);
1437 }
1438
1439 /**
1440 * Returns the index within this string of the last occurrence of the
1441 * specified substring. The last occurrence of the empty string "" is
1442 * considered to occur at the index value {@code this.length()}.
1443 *
1444 * <p>The returned index is the largest value {@code k} for which:
1445 * <pre>{@code
1446 * this.toString().startsWith(str, k)
1447 * }</pre>
1448 * If no such value of {@code k} exists, then {@code -1} is returned.
1449 *
1450 * @param str the substring to search for.
1451 * @return the index of the last occurrence of the specified substring,
1452 * or {@code -1} if there is no such occurrence.
1453 */
1454 public int lastIndexOf(String str) {
1455 return lastIndexOf(str, count);
1456 }
1457
1458 /**
1459 * Returns the index within this string of the last occurrence of the
1460 * specified substring, searching backward starting at the specified index.
1461 *
1462 * <p>The returned index is the largest value {@code k} for which:
1463 * <pre>{@code
1464 * k <= Math.min(fromIndex, this.length()) &&
1465 * this.toString().startsWith(str, k)
1466 * }</pre>
1467 * If no such value of {@code k} exists, then {@code -1} is returned.
1468 *
1469 * @param str the substring to search for.
1470 * @param fromIndex the index to start the search from.
1471 * @return the index of the last occurrence of the specified substring,
1472 * searching backward from the specified index,
1473 * or {@code -1} if there is no such occurrence.
1474 */
1475 public int lastIndexOf(String str, int fromIndex) {
1476 byte[] value = this.value;
1477 int count = this.count;
1478 byte coder = this.coder;
1479 checkOffset(count, value.length >> coder);
1480 return String.lastIndexOf(value, coder, count, str, fromIndex);
1481 }
1482
1483 /**
1484 * Causes this character sequence to be replaced by the reverse of
1485 * the sequence. If there are any surrogate pairs included in the
1486 * sequence, these are treated as single characters for the
1487 * reverse operation. Thus, the order of the high-low surrogates
1488 * is never reversed.
1489 *
1490 * Let <i>n</i> be the character length of this character sequence
1491 * (not the length in {@code char} values) just prior to
1492 * execution of the {@code reverse} method. Then the
1493 * character at index <i>k</i> in the new character sequence is
1494 * equal to the character at index <i>n-k-1</i> in the old
1495 * character sequence.
1496 *
1497 * <p>Note that the reverse operation may result in producing
1498 * surrogate pairs that were unpaired low-surrogates and
1499 * high-surrogates before the operation. For example, reversing
|