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