AbstractStringBuilder.java
0001 /** 0002 * @(#)AbstractStringBuilder.java 1.15 05/11/17 0003 * 0004 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 0005 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 0006 */ 0007 0008 package java.lang; 0009 0010 import sun.misc.FloatingDecimal; 0011 import java.util.Arrays; 0012 0013 /*** 0014 * A mutable sequence of characters. 0015 * <p> 0016 * Implements a modifiable string. At any point in time it contains some 0017 * particular sequence of characters, but the length and content of the 0018 * sequence can be changed through certain method calls. 0019 * 0020 * @author Michael McCloskey 0021 * @version 1.15, 11/17/05 0022 * @since 1.5 0023 */ 0024 abstract class AbstractStringBuilder implements Appendable, CharSequence { 0025 /*** 0026 * The value is used for character storage. 0027 */ 0028 char value[]; 0029 0030 /*** 0031 * The count is the number of characters used. 0032 */ 0033 int count; 0034 0035 /*** 0036 * This no-arg constructor is necessary for serialization of subclasses. 0037 */ 0038 AbstractStringBuilder() { 0039 } 0040 0041 /*** 0042 * Creates an AbstractStringBuilder of the specified capacity. 0043 */ 0044 AbstractStringBuilder(int capacity) { 0045 value = new char[capacity]; 0046 } 0047 0048 /*** 0049 * Returns the length (character count). 0050 * 0051 * @return the length of the sequence of characters currently 0052 * represented by this object 0053 */ 0054 public int length() { 0055 return count; 0056 } 0057 0058 /*** 0059 * Returns the current capacity. The capacity is the amount of storage 0060 * available for newly inserted characters, beyond which an allocation 0061 * will occur. 0062 * 0063 * @return the current capacity 0064 */ 0065 public int capacity() { 0066 return value.length; 0067 } 0068 0069 /*** 0070 * Ensures that the capacity is at least equal to the specified minimum. 0071 * If the current capacity is less than the argument, then a new internal 0072 * array is allocated with greater capacity. The new capacity is the 0073 * larger of: 0074 * <ul> 0075 * <li>The <code>minimumCapacity</code> argument. 0076 * <li>Twice the old capacity, plus <code>2</code>. 0077 * </ul> 0078 * If the <code>minimumCapacity</code> argument is nonpositive, this 0079 * method takes no action and simply returns. 0080 * 0081 * @param minimumCapacity the minimum desired capacity. 0082 */ 0083 public void ensureCapacity(int minimumCapacity) { 0084 if (minimumCapacity > value.length) { 0085 expandCapacity(minimumCapacity); 0086 } 0087 } 0088 0089 /*** 0090 * This implements the expansion semantics of ensureCapacity with no 0091 * size check or synchronization. 0092 */ 0093 void expandCapacity(int minimumCapacity) { 0094 int newCapacity = (value.length + 1) * 2; 0095 if (newCapacity < 0) { 0096 newCapacity = Integer.MAX_VALUE; 0097 } else if (minimumCapacity > newCapacity) { 0098 newCapacity = minimumCapacity; 0099 } 0100 value = Arrays.copyOf(value, newCapacity); 0101 } 0102 0103 /*** 0104 * Attempts to reduce storage used for the character sequence. 0105 * If the buffer is larger than necessary to hold its current sequence of 0106 * characters, then it may be resized to become more space efficient. 0107 * Calling this method may, but is not required to, affect the value 0108 * returned by a subsequent call to the {@link #capacity()} method. 0109 */ 0110 public void trimToSize() { 0111 if (count < value.length) { 0112 value = Arrays.copyOf(value, count); 0113 } 0114 } 0115 0116 /*** 0117 * Sets the length of the character sequence. 0118 * The sequence is changed to a new character sequence 0119 * whose length is specified by the argument. For every nonnegative 0120 * index <i>k</i> less than <code>newLength</code>, the character at 0121 * index <i>k</i> in the new character sequence is the same as the 0122 * character at index <i>k</i> in the old sequence if <i>k</i> is less 0123 * than the length of the old character sequence; otherwise, it is the 0124 * null character <code>'\u0000'</code>. 0125 * 0126 * In other words, if the <code>newLength</code> argument is less than 0127 * the current length, the length is changed to the specified length. 0128 * <p> 0129 * If the <code>newLength</code> argument is greater than or equal 0130 * to the current length, sufficient null characters 0131 * (<code>'\u0000'</code>) are appended so that 0132 * length becomes the <code>newLength</code> argument. 0133 * <p> 0134 * The <code>newLength</code> argument must be greater than or equal 0135 * to <code>0</code>. 0136 * 0137 * @param newLength the new length 0138 * @throws IndexOutOfBoundsException if the 0139 * <code>newLength</code> argument is negative. 0140 */ 0141 public void setLength(int newLength) { 0142 if (newLength < 0) 0143 throw new StringIndexOutOfBoundsException(newLength); 0144 if (newLength > value.length) 0145 expandCapacity(newLength); 0146 0147 if (count < newLength) { 0148 for (; count < newLength; count++) 0149 value[count] = '\0'; 0150 } else { 0151 count = newLength; 0152 } 0153 } 0154 0155 /*** 0156 * Returns the <code>char</code> value in this sequence at the specified index. 0157 * The first <code>char</code> value is at index <code>0</code>, the next at index 0158 * <code>1</code>, and so on, as in array indexing. 0159 * <p> 0160 * The index argument must be greater than or equal to 0161 * <code>0</code>, and less than the length of this sequence. 0162 * 0163 * <p>If the <code>char</code> value specified by the index is a 0164 * <a href="Character.html#unicode">surrogate</a>, the surrogate 0165 * value is returned. 0166 * 0167 * @param index the index of the desired <code>char</code> value. 0168 * @return the <code>char</code> value at the specified index. 0169 * @throws IndexOutOfBoundsException if <code>index</code> is 0170 * negative or greater than or equal to <code>length()</code>. 0171 */ 0172 public char charAt(int index) { 0173 if ((index < 0) || (index >= count)) 0174 throw new StringIndexOutOfBoundsException(index); 0175 return value[index]; 0176 } 0177 0178 /*** 0179 * Returns the character (Unicode code point) at the specified 0180 * index. The index refers to <code>char</code> values 0181 * (Unicode code units) and ranges from <code>0</code> to 0182 * {@link #length()}<code> - 1</code>. 0183 * 0184 * <p> If the <code>char</code> value specified at the given index 0185 * is in the high-surrogate range, the following index is less 0186 * than the length of this sequence, and the 0187 * <code>char</code> value at the following index is in the 0188 * low-surrogate range, then the supplementary code point 0189 * corresponding to this surrogate pair is returned. Otherwise, 0190 * the <code>char</code> value at the given index is returned. 0191 * 0192 * @param index the index to the <code>char</code> values 0193 * @return the code point value of the character at the 0194 * <code>index</code> 0195 * @exception IndexOutOfBoundsException if the <code>index</code> 0196 * argument is negative or not less than the length of this 0197 * sequence. 0198 */ 0199 public int codePointAt(int index) { 0200 if ((index < 0) || (index >= count)) { 0201 throw new StringIndexOutOfBoundsException(index); 0202 } 0203 return Character.codePointAt(value, index); 0204 } 0205 0206 /*** 0207 * Returns the character (Unicode code point) before the specified 0208 * index. The index refers to <code>char</code> values 0209 * (Unicode code units) and ranges from <code>1</code> to {@link 0210 * #length()}. 0211 * 0212 * <p> If the <code>char</code> value at <code>(index - 1)</code> 0213 * is in the low-surrogate range, <code>(index - 2)</code> is not 0214 * negative, and the <code>char</code> value at <code>(index - 0215 * 2)</code> is in the high-surrogate range, then the 0216 * supplementary code point value of the surrogate pair is 0217 * returned. If the <code>char</code> value at <code>index - 0218 * 1</code> is an unpaired low-surrogate or a high-surrogate, the 0219 * surrogate value is returned. 0220 * 0221 * @param index the index following the code point that should be returned 0222 * @return the Unicode code point value before the given index. 0223 * @exception IndexOutOfBoundsException if the <code>index</code> 0224 * argument is less than 1 or greater than the length 0225 * of this sequence. 0226 */ 0227 public int codePointBefore(int index) { 0228 int i = index - 1; 0229 if ((i < 0) || (i >= count)) { 0230 throw new StringIndexOutOfBoundsException(index); 0231 } 0232 return Character.codePointBefore(value, index); 0233 } 0234 0235 /*** 0236 * Returns the number of Unicode code points in the specified text 0237 * range of this sequence. The text range begins at the specified 0238 * <code>beginIndex</code> and extends to the <code>char</code> at 0239 * index <code>endIndex - 1</code>. Thus the length (in 0240 * <code>char</code>s) of the text range is 0241 * <code>endIndex-beginIndex</code>. Unpaired surrogates within 0242 * this sequence count as one code point each. 0243 * 0244 * @param beginIndex the index to the first <code>char</code> of 0245 * the text range. 0246 * @param endIndex the index after the last <code>char</code> of 0247 * the text range. 0248 * @return the number of Unicode code points in the specified text 0249 * range 0250 * @exception IndexOutOfBoundsException if the 0251 * <code>beginIndex</code> is negative, or <code>endIndex</code> 0252 * is larger than the length of this sequence, or 0253 * <code>beginIndex</code> is larger than <code>endIndex</code>. 0254 */ 0255 public int codePointCount(int beginIndex, int endIndex) { 0256 if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) { 0257 throw new IndexOutOfBoundsException(); 0258 } 0259 return Character.codePointCountImpl(value, beginIndex, endIndex-beginIndex); 0260 } 0261 0262 /*** 0263 * Returns the index within this sequence that is offset from the 0264 * given <code>index</code> by <code>codePointOffset</code> code 0265 * points. Unpaired surrogates within the text range given by 0266 * <code>index</code> and <code>codePointOffset</code> count as 0267 * one code point each. 0268 * 0269 * @param index the index to be offset 0270 * @param codePointOffset the offset in code points 0271 * @return the index within this sequence 0272 * @exception IndexOutOfBoundsException if <code>index</code> 0273 * is negative or larger then the length of this sequence, 0274 * or if <code>codePointOffset</code> is positive and the subsequence 0275 * starting with <code>index</code> has fewer than 0276 * <code>codePointOffset</code> code points, 0277 * or if <code>codePointOffset</code> is negative and the subsequence 0278 * before <code>index</code> has fewer than the absolute value of 0279 * <code>codePointOffset</code> code points. 0280 */ 0281 public int offsetByCodePoints(int index, int codePointOffset) { 0282 if (index < 0 || index > count) { 0283 throw new IndexOutOfBoundsException(); 0284 } 0285 return Character.offsetByCodePointsImpl(value, 0, count, 0286 index, codePointOffset); 0287 } 0288 0289 /*** 0290 * Characters are copied from this sequence into the 0291 * destination character array <code>dst</code>. The first character to 0292 * be copied is at index <code>srcBegin</code>; the last character to 0293 * be copied is at index <code>srcEnd-1</code>. The total number of 0294 * characters to be copied is <code>srcEnd-srcBegin</code>. The 0295 * characters are copied into the subarray of <code>dst</code> starting 0296 * at index <code>dstBegin</code> and ending at index: 0297 * <p><blockquote><pre> 0298 * dstbegin + (srcEnd-srcBegin) - 1 0299 * </pre></blockquote> 0300 * 0301 * @param srcBegin start copying at this offset. 0302 * @param srcEnd stop copying at this offset. 0303 * @param dst the array to copy the data into. 0304 * @param dstBegin offset into <code>dst</code>. 0305 * @throws NullPointerException if <code>dst</code> is 0306 * <code>null</code>. 0307 * @throws IndexOutOfBoundsException if any of the following is true: 0308 * <ul> 0309 * <li><code>srcBegin</code> is negative 0310 * <li><code>dstBegin</code> is negative 0311 * <li>the <code>srcBegin</code> argument is greater than 0312 * the <code>srcEnd</code> argument. 0313 * <li><code>srcEnd</code> is greater than 0314 * <code>this.length()</code>. 0315 * <li><code>dstBegin+srcEnd-srcBegin</code> is greater than 0316 * <code>dst.length</code> 0317 * </ul> 0318 */ 0319 public void getChars(int srcBegin, int srcEnd, char dst[], 0320 int dstBegin) 0321 { 0322 if (srcBegin < 0) 0323 throw new StringIndexOutOfBoundsException(srcBegin); 0324 if ((srcEnd < 0) || (srcEnd > count)) 0325 throw new StringIndexOutOfBoundsException(srcEnd); 0326 if (srcBegin > srcEnd) 0327 throw new StringIndexOutOfBoundsException("srcBegin > srcEnd"); 0328 System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin); 0329 } 0330 0331 /*** 0332 * The character at the specified index is set to <code>ch</code>. This 0333 * sequence is altered to represent a new character sequence that is 0334 * identical to the old character sequence, except that it contains the 0335 * character <code>ch</code> at position <code>index</code>. 0336 * <p> 0337 * The index argument must be greater than or equal to 0338 * <code>0</code>, and less than the length of this sequence. 0339 * 0340 * @param index the index of the character to modify. 0341 * @param ch the new character. 0342 * @throws IndexOutOfBoundsException if <code>index</code> is 0343 * negative or greater than or equal to <code>length()</code>. 0344 */ 0345 public void setCharAt(int index, char ch) { 0346 if ((index < 0) || (index >= count)) 0347 throw new StringIndexOutOfBoundsException(index); 0348 value[index] = ch; 0349 } 0350 0351 /*** 0352 * Appends the string representation of the <code>Object</code> 0353 * argument. 0354 * <p> 0355 * The argument is converted to a string as if by the method 0356 * <code>String.valueOf</code>, and the characters of that 0357 * string are then appended to this sequence. 0358 * 0359 * @param obj an <code>Object</code>. 0360 * @return a reference to this object. 0361 */ 0362 public AbstractStringBuilder append(Object obj) { 0363 return append(String.valueOf(obj)); 0364 } 0365 0366 /*** 0367 * Appends the specified string to this character sequence. 0368 * <p> 0369 * The characters of the <code>String</code> argument are appended, in 0370 * order, increasing the length of this sequence by the length of the 0371 * argument. If <code>str</code> is <code>null</code>, then the four 0372 * characters <code>"null"</code> are appended. 0373 * <p> 0374 * Let <i>n</i> be the length of this character sequence just prior to 0375 * execution of the <code>append</code> method. Then the character at 0376 * index <i>k</i> in the new character sequence is equal to the character 0377 * at index <i>k</i> in the old character sequence, if <i>k</i> is less 0378 * than <i>n</i>; otherwise, it is equal to the character at index 0379 * <i>k-n</i> in the argument <code>str</code>. 0380 * 0381 * @param str a string. 0382 * @return a reference to this object. 0383 */ 0384 public AbstractStringBuilder append(String str) { 0385 if (str == null) str = "null"; 0386 int len = str.length(); 0387 if (len == 0) return this; 0388 int newCount = count + len; 0389 if (newCount > value.length) 0390 expandCapacity(newCount); 0391 str.getChars(0, len, value, count); 0392 count = newCount; 0393 return this; 0394 } 0395 0396 // Documentation in subclasses because of synchro difference 0397 public AbstractStringBuilder append(StringBuffer sb) { 0398 if (sb == null) 0399 return append("null"); 0400 int len = sb.length(); 0401 int newCount = count + len; 0402 if (newCount > value.length) 0403 expandCapacity(newCount); 0404 sb.getChars(0, len, value, count); 0405 count = newCount; 0406 return this; 0407 } 0408 0409 // Documentation in subclasses because of synchro difference 0410 public AbstractStringBuilder append(CharSequence s) { 0411 if (s == null) 0412 s = "null"; 0413 if (s instanceof String) 0414 return this.append((String)s); 0415 if (s instanceof StringBuffer) 0416 return this.append((StringBuffer)s); 0417 return this.append(s, 0, s.length()); 0418 } 0419 0420 /*** 0421 * Appends a subsequence of the specified <code>CharSequence</code> to this 0422 * sequence. 0423 * <p> 0424 * Characters of the argument <code>s</code>, starting at 0425 * index <code>start</code>, are appended, in order, to the contents of 0426 * this sequence up to the (exclusive) index <code>end</code>. The length 0427 * of this sequence is increased by the value of <code>end - start</code>. 0428 * <p> 0429 * Let <i>n</i> be the length of this character sequence just prior to 0430 * execution of the <code>append</code> method. Then the character at 0431 * index <i>k</i> in this character sequence becomes equal to the 0432 * character at index <i>k</i> in this sequence, if <i>k</i> is less than 0433 * <i>n</i>; otherwise, it is equal to the character at index 0434 * <i>k+start-n</i> in the argument <code>s</code>. 0435 * <p> 0436 * If <code>s</code> is <code>null</code>, then this method appends 0437 * characters as if the s parameter was a sequence containing the four 0438 * characters <code>"null"</code>. 0439 * 0440 * @param s the sequence to append. 0441 * @param start the starting index of the subsequence to be appended. 0442 * @param end the end index of the subsequence to be appended. 0443 * @return a reference to this object. 0444 * @throws IndexOutOfBoundsException if 0445 * <code>start</code> or <code>end</code> are negative, or 0446 * <code>start</code> is greater than <code>end</code> or 0447 * <code>end</code> is greater than <code>s.length()</code> 0448 */ 0449 public AbstractStringBuilder append(CharSequence s, int start, int end) { 0450 if (s == null) 0451 s = "null"; 0452 if ((start < 0) || (end < 0) || (start > end) || (end > s.length())) 0453 throw new IndexOutOfBoundsException( 0454 "start " + start + ", end " + end + ", s.length() " 0455 + s.length()); 0456 int len = end - start; 0457 if (len == 0) 0458 return this; 0459 int newCount = count + len; 0460 if (newCount > value.length) 0461 expandCapacity(newCount); 0462 for (int i=start; i<end; i++) 0463 value[count++] = s.charAt(i); 0464 count = newCount; 0465 return this; 0466 } 0467 0468 /*** 0469 * Appends the string representation of the <code>char</code> array 0470 * argument to this sequence. 0471 * <p> 0472 * The characters of the array argument are appended, in order, to 0473 * the contents of this sequence. The length of this sequence 0474 * increases by the length of the argument. 0475 * <p> 0476 * The overall effect is exactly as if the argument were converted to 0477 * a string by the method {@link String#valueOf(char[])} and the 0478 * characters of that string were then {@link #append(String) appended} 0479 * to this character sequence. 0480 * 0481 * @param str the characters to be appended. 0482 * @return a reference to this object. 0483 */ 0484 public AbstractStringBuilder append(char str[]) { 0485 int newCount = count + str.length; 0486 if (newCount > value.length) 0487 expandCapacity(newCount); 0488 System.arraycopy(str, 0, value, count, str.length); 0489 count = newCount; 0490 return this; 0491 } 0492 0493 /*** 0494 * Appends the string representation of a subarray of the 0495 * <code>char</code> array argument to this sequence. 0496 * <p> 0497 * Characters of the <code>char</code> array <code>str</code>, starting at 0498 * index <code>offset</code>, are appended, in order, to the contents 0499 * of this sequence. The length of this sequence increases 0500 * by the value of <code>len</code>. 0501 * <p> 0502 * The overall effect is exactly as if the arguments were converted to 0503 * a string by the method {@link String#valueOf(char[],int,int)} and the 0504 * characters of that string were then {@link #append(String) appended} 0505 * to this character sequence. 0506 * 0507 * @param str the characters to be appended. 0508 * @param offset the index of the first <code>char</code> to append. 0509 * @param len the number of <code>char</code>s to append. 0510 * @return a reference to this object. 0511 */ 0512 public AbstractStringBuilder append(char str[], int offset, int len) { 0513 int newCount = count + len; 0514 if (newCount > value.length) 0515 expandCapacity(newCount); 0516 System.arraycopy(str, offset, value, count, len); 0517 count = newCount; 0518 return this; 0519 } 0520 0521 /*** 0522 * Appends the string representation of the <code>boolean</code> 0523 * argument to the sequence. 0524 * <p> 0525 * The argument is converted to a string as if by the method 0526 * <code>String.valueOf</code>, and the characters of that 0527 * string are then appended to this sequence. 0528 * 0529 * @param b a <code>boolean</code>. 0530 * @return a reference to this object. 0531 */ 0532 public AbstractStringBuilder append(boolean b) { 0533 if (b) { 0534 int newCount = count + 4; 0535 if (newCount > value.length) 0536 expandCapacity(newCount); 0537 value[count++] = 't'; 0538 value[count++] = 'r'; 0539 value[count++] = 'u'; 0540 value[count++] = 'e'; 0541 } else { 0542 int newCount = count + 5; 0543 if (newCount > value.length) 0544 expandCapacity(newCount); 0545 value[count++] = 'f'; 0546 value[count++] = 'a'; 0547 value[count++] = 'l'; 0548 value[count++] = 's'; 0549 value[count++] = 'e'; 0550 } 0551 return this; 0552 } 0553 0554 /*** 0555 * Appends the string representation of the <code>char</code> 0556 * argument to this sequence. 0557 * <p> 0558 * The argument is appended to the contents of this sequence. 0559 * The length of this sequence increases by <code>1</code>. 0560 * <p> 0561 * The overall effect is exactly as if the argument were converted to 0562 * a string by the method {@link String#valueOf(char)} and the character 0563 * in that string were then {@link #append(String) appended} to this 0564 * character sequence. 0565 * 0566 * @param c a <code>char</code>. 0567 * @return a reference to this object. 0568 */ 0569 public AbstractStringBuilder append(char c) { 0570 int newCount = count + 1; 0571 if (newCount > value.length) 0572 expandCapacity(newCount); 0573 value[count++] = c; 0574 return this; 0575 } 0576 0577 /*** 0578 * Appends the string representation of the <code>int</code> 0579 * argument to this sequence. 0580 * <p> 0581 * The argument is converted to a string as if by the method 0582 * <code>String.valueOf</code>, and the characters of that 0583 * string are then appended to this sequence. 0584 * 0585 * @param i an <code>int</code>. 0586 * @return a reference to this object. 0587 */ 0588 public AbstractStringBuilder append(int i) { 0589 if (i == Integer.MIN_VALUE) { 0590 append("-2147483648"); 0591 return this; 0592 } 0593 int appendedLength = (i < 0) ? stringSizeOfInt(-i) + 1 0594 : stringSizeOfInt(i); 0595 int spaceNeeded = count + appendedLength; 0596 if (spaceNeeded > value.length) 0597 expandCapacity(spaceNeeded); 0598 Integer.getChars(i, spaceNeeded, value); 0599 count = spaceNeeded; 0600 return this; 0601 } 0602 0603 final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999, 0604 99999999, 999999999, Integer.MAX_VALUE }; 0605 0606 // Requires positive x 0607 static int stringSizeOfInt(int x) { 0608 for (int i=0; ; i++) 0609 if (x <= sizeTable[i]) 0610 return i+1; 0611 } 0612 0613 /*** 0614 * Appends the string representation of the <code>long</code> 0615 * argument to this sequence. 0616 * <p> 0617 * The argument is converted to a string as if by the method 0618 * <code>String.valueOf</code>, and the characters of that 0619 * string are then appended to this sequence. 0620 * 0621 * @param l a <code>long</code>. 0622 * @return a reference to this object. 0623 */ 0624 public AbstractStringBuilder append(long l) { 0625 if (l == Long.MIN_VALUE) { 0626 append("-9223372036854775808"); 0627 return this; 0628 } 0629 int appendedLength = (l < 0) ? stringSizeOfLong(-l) + 1 0630 : stringSizeOfLong(l); 0631 int spaceNeeded = count + appendedLength; 0632 if (spaceNeeded > value.length) 0633 expandCapacity(spaceNeeded); 0634 Long.getChars(l, spaceNeeded, value); 0635 count = spaceNeeded; 0636 return this; 0637 } 0638 0639 // Requires positive x 0640 static int stringSizeOfLong(long x) { 0641 long p = 10; 0642 for (int i=1; i<19; i++) { 0643 if (x < p) 0644 return i; 0645 p = 10*p; 0646 } 0647 return 19; 0648 } 0649 0650 /*** 0651 * Appends the string representation of the <code>float</code> 0652 * argument to this sequence. 0653 * <p> 0654 * The argument is converted to a string as if by the method 0655 * <code>String.valueOf</code>, and the characters of that 0656 * string are then appended to this string sequence. 0657 * 0658 * @param f a <code>float</code>. 0659 * @return a reference to this object. 0660 */ 0661 public AbstractStringBuilder append(float f) { 0662 new FloatingDecimal(f).appendTo(this); 0663 return this; 0664 } 0665 0666 /*** 0667 * Appends the string representation of the <code>double</code> 0668 * argument to this sequence. 0669 * <p> 0670 * The argument is converted to a string as if by the method 0671 * <code>String.valueOf</code>, and the characters of that 0672 * string are then appended to this sequence. 0673 * 0674 * @param d a <code>double</code>. 0675 * @return a reference to this object. 0676 */ 0677 public AbstractStringBuilder append(double d) { 0678 new FloatingDecimal(d).appendTo(this); 0679 return this; 0680 } 0681 0682 /*** 0683 * Removes the characters in a substring of this sequence. 0684 * The substring begins at the specified <code>start</code> and extends to 0685 * the character at index <code>end - 1</code> or to the end of the 0686 * sequence if no such character exists. If 0687 * <code>start</code> is equal to <code>end</code>, no changes are made. 0688 * 0689 * @param start The beginning index, inclusive. 0690 * @param end The ending index, exclusive. 0691 * @return This object. 0692 * @throws StringIndexOutOfBoundsException if <code>start</code> 0693 * is negative, greater than <code>length()</code>, or 0694 * greater than <code>end</code>. 0695 */ 0696 public AbstractStringBuilder delete(int start, int end) { 0697 if (start < 0) 0698 throw new StringIndexOutOfBoundsException(start); 0699 if (end > count) 0700 end = count; 0701 if (start > end) 0702 throw new StringIndexOutOfBoundsException(); 0703 int len = end - start; 0704 if (len > 0) { 0705 System.arraycopy(value, start+len, value, start, count-end); 0706 count -= len; 0707 } 0708 return this; 0709 } 0710 0711 /*** 0712 * Appends the string representation of the <code>codePoint</code> 0713 * argument to this sequence. 0714 * 0715 * <p> The argument is appended to the contents of this sequence. 0716 * The length of this sequence increases by 0717 * {@link Character#charCount(int) Character.charCount(codePoint)}. 0718 * 0719 * <p> The overall effect is exactly as if the argument were 0720 * converted to a <code>char</code> array by the method {@link 0721 * Character#toChars(int)} and the character in that array were 0722 * then {@link #append(char[]) appended} to this character 0723 * sequence. 0724 * 0725 * @param codePoint a Unicode code point 0726 * @return a reference to this object. 0727 * @exception IllegalArgumentException if the specified 0728 * <code>codePoint</code> isn't a valid Unicode code point 0729 */ 0730 public AbstractStringBuilder appendCodePoint(int codePoint) { 0731 if (!Character.isValidCodePoint(codePoint)) { 0732 throw new IllegalArgumentException(); 0733 } 0734 int n = 1; 0735 if (codePoint >= Character.MIN_SUPPLEMENTARY_CODE_POINT) { 0736 n++; 0737 } 0738 int newCount = count + n; 0739 if (newCount > value.length) { 0740 expandCapacity(newCount); 0741 } 0742 if (n == 1) { 0743 value[count++] = (char) codePoint; 0744 } else { 0745 Character.toSurrogates(codePoint, value, count); 0746 count += n; 0747 } 0748 return this; 0749 } 0750 0751 /*** 0752 * Removes the <code>char</code> at the specified position in this 0753 * sequence. This sequence is shortened by one <code>char</code>. 0754 * 0755 * <p>Note: If the character at the given index is a supplementary 0756 * character, this method does not remove the entire character. If 0757 * correct handling of supplementary characters is required, 0758 * determine the number of <code>char</code>s to remove by calling 0759 * <code>Character.charCount(thisSequence.codePointAt(index))</code>, 0760 * where <code>thisSequence</code> is this sequence. 0761 * 0762 * @param index Index of <code>char</code> to remove 0763 * @return This object. 0764 * @throws StringIndexOutOfBoundsException if the <code>index</code> 0765 * is negative or greater than or equal to 0766 * <code>length()</code>. 0767 */ 0768 public AbstractStringBuilder deleteCharAt(int index) { 0769 if ((index < 0) || (index >= count)) 0770 throw new StringIndexOutOfBoundsException(index); 0771 System.arraycopy(value, index+1, value, index, count-index-1); 0772 count--; 0773 return this; 0774 } 0775 0776 /*** 0777 * Replaces the characters in a substring of this sequence 0778 * with characters in the specified <code>String</code>. The substring 0779 * begins at the specified <code>start</code> and extends to the character 0780 * at index <code>end - 1</code> or to the end of the 0781 * sequence if no such character exists. First the 0782 * characters in the substring are removed and then the specified 0783 * <code>String</code> is inserted at <code>start</code>. (This 0784 * sequence will be lengthened to accommodate the 0785 * specified String if necessary.) 0786 * 0787 * @param start The beginning index, inclusive. 0788 * @param end The ending index, exclusive. 0789 * @param str String that will replace previous contents. 0790 * @return This object. 0791 * @throws StringIndexOutOfBoundsException if <code>start</code> 0792 * is negative, greater than <code>length()</code>, or 0793 * greater than <code>end</code>. 0794 */ 0795 public AbstractStringBuilder replace(int start, int end, String str) { 0796 if (start < 0) 0797 throw new StringIndexOutOfBoundsException(start); 0798 if (start > count) 0799 throw new StringIndexOutOfBoundsException("start > length()"); 0800 if (start > end) 0801 throw new StringIndexOutOfBoundsException("start > end"); 0802 0803 if (end > count) 0804 end = count; 0805 int len = str.length(); 0806 int newCount = count + len - (end - start); 0807 if (newCount > value.length) 0808 expandCapacity(newCount); 0809 0810 System.arraycopy(value, end, value, start + len, count - end); 0811 str.getChars(value, start); 0812 count = newCount; 0813 return this; 0814 } 0815 0816 /*** 0817 * Returns a new <code>String</code> that contains a subsequence of 0818 * characters currently contained in this character sequence. The 0819 * substring begins at the specified index and extends to the end of 0820 * this sequence. 0821 * 0822 * @param start The beginning index, inclusive. 0823 * @return The new string. 0824 * @throws StringIndexOutOfBoundsException if <code>start</code> is 0825 * less than zero, or greater than the length of this object. 0826 */ 0827 public String substring(int start) { 0828 return substring(start, count); 0829 } 0830 0831 /*** 0832 * Returns a new character sequence that is a subsequence of this sequence. 0833 * 0834 * <p> An invocation of this method of the form 0835 * 0836 * <blockquote><pre> 0837 * sb.subSequence(begin, end)</pre></blockquote> 0838 * 0839 * behaves in exactly the same way as the invocation 0840 * 0841 * <blockquote><pre> 0842 * sb.substring(begin, end)</pre></blockquote> 0843 * 0844 * This method is provided so that this class can 0845 * implement the {@link CharSequence} interface. </p> 0846 * 0847 * @param start the start index, inclusive. 0848 * @param end the end index, exclusive. 0849 * @return the specified subsequence. 0850 * 0851 * @throws IndexOutOfBoundsException 0852 * if <tt>start</tt> or <tt>end</tt> are negative, 0853 * if <tt>end</tt> is greater than <tt>length()</tt>, 0854 * or if <tt>start</tt> is greater than <tt>end</tt> 0855 * @spec JSR-51 0856 */ 0857 public CharSequence subSequence(int start, int end) { 0858 return substring(start, end); 0859 } 0860 0861 /*** 0862 * Returns a new <code>String</code> that contains a subsequence of 0863 * characters currently contained in this sequence. The 0864 * substring begins at the specified <code>start</code> and 0865 * extends to the character at index <code>end - 1</code>. 0866 * 0867 * @param start The beginning index, inclusive. 0868 * @param end The ending index, exclusive. 0869 * @return The new string. 0870 * @throws StringIndexOutOfBoundsException if <code>start</code> 0871 * or <code>end</code> are negative or greater than 0872 * <code>length()</code>, or <code>start</code> is 0873 * greater than <code>end</code>. 0874 */ 0875 public String substring(int start, int end) { 0876 if (start < 0) 0877 throw new StringIndexOutOfBoundsException(start); 0878 if (end > count) 0879 throw new StringIndexOutOfBoundsException(end); 0880 if (start > end) 0881 throw new StringIndexOutOfBoundsException(end - start); 0882 return new String(value, start, end - start); 0883 } 0884 0885 /*** 0886 * Inserts the string representation of a subarray of the <code>str</code> 0887 * array argument into this sequence. The subarray begins at the 0888 * specified <code>offset</code> and extends <code>len</code> <code>char</code>s. 0889 * The characters of the subarray are inserted into this sequence at 0890 * the position indicated by <code>index</code>. The length of this 0891 * sequence increases by <code>len</code> <code>char</code>s. 0892 * 0893 * @param index position at which to insert subarray. 0894 * @param str A <code>char</code> array. 0895 * @param offset the index of the first <code>char</code> in subarray to 0896 * be inserted. 0897 * @param len the number of <code>char</code>s in the subarray to 0898 * be inserted. 0899 * @return This object 0900 * @throws StringIndexOutOfBoundsException if <code>index</code> 0901 * is negative or greater than <code>length()</code>, or 0902 * <code>offset</code> or <code>len</code> are negative, or 0903 * <code>(offset+len)</code> is greater than 0904 * <code>str.length</code>. 0905 */ 0906 public AbstractStringBuilder insert(int index, char str[], int offset, 0907 int len) 0908 { 0909 if ((index < 0) || (index > length())) 0910 throw new StringIndexOutOfBoundsException(index); 0911 if ((offset < 0) || (len < 0) || (offset > str.length - len)) 0912 throw new StringIndexOutOfBoundsException( 0913 "offset " + offset + ", len " + len + ", str.length " 0914 + str.length); 0915 int newCount = count + len; 0916 if (newCount > value.length) 0917 expandCapacity(newCount); 0918 System.arraycopy(value, index, value, index + len, count - index); 0919 System.arraycopy(str, offset, value, index, len); 0920 count = newCount; 0921 return this; 0922 } 0923 0924 /*** 0925 * Inserts the string representation of the <code>Object</code> 0926 * argument into this character sequence. 0927 * <p> 0928 * The second argument is converted to a string as if by the method 0929 * <code>String.valueOf</code>, and the characters of that 0930 * string are then inserted into this sequence at the indicated 0931 * offset. 0932 * <p> 0933 * The offset argument must be greater than or equal to 0934 * <code>0</code>, and less than or equal to the length of this 0935 * sequence. 0936 * 0937 * @param offset the offset. 0938 * @param obj an <code>Object</code>. 0939 * @return a reference to this object. 0940 * @throws StringIndexOutOfBoundsException if the offset is invalid. 0941 */ 0942 public AbstractStringBuilder insert(int offset, Object obj) { 0943 return insert(offset, String.valueOf(obj)); 0944 } 0945 0946 /*** 0947 * Inserts the string into this character sequence. 0948 * <p> 0949 * The characters of the <code>String</code> argument are inserted, in 0950 * order, into this sequence at the indicated offset, moving up any 0951 * characters originally above that position and increasing the length 0952 * of this sequence by the length of the argument. If 0953 * <code>str</code> is <code>null</code>, then the four characters 0954 * <code>"null"</code> are inserted into this sequence. 0955 * <p> 0956 * The character at index <i>k</i> in the new character sequence is 0957 * equal to: 0958 * <ul> 0959 * <li>the character at index <i>k</i> in the old character sequence, if 0960 * <i>k</i> is less than <code>offset</code> 0961 * <li>the character at index <i>k</i><code>-offset</code> in the 0962 * argument <code>str</code>, if <i>k</i> is not less than 0963 * <code>offset</code> but is less than <code>offset+str.length()</code> 0964 * <li>the character at index <i>k</i><code>-str.length()</code> in the 0965 * old character sequence, if <i>k</i> is not less than 0966 * <code>offset+str.length()</code> 0967 * </ul><p> 0968 * The offset argument must be greater than or equal to 0969 * <code>0</code>, and less than or equal to the length of this 0970 * sequence. 0971 * 0972 * @param offset the offset. 0973 * @param str a string. 0974 * @return a reference to this object. 0975 * @throws StringIndexOutOfBoundsException if the offset is invalid. 0976 */ 0977 public AbstractStringBuilder insert(int offset, String str) { 0978 if ((offset < 0) || (offset > length())) 0979 throw new StringIndexOutOfBoundsException(offset); 0980 if (str == null) 0981 str = "null"; 0982 int len = str.length(); 0983 int newCount = count + len; 0984 if (newCount > value.length) 0985 expandCapacity(newCount); 0986 System.arraycopy(value, offset, value, offset + len, count - offset); 0987 str.getChars(value, offset); 0988 count = newCount; 0989 return this; 0990 } 0991 0992 /*** 0993 * Inserts the string representation of the <code>char</code> array 0994 * argument into this sequence. 0995 * <p> 0996 * The characters of the array argument are inserted into the 0997 * contents of this sequence at the position indicated by 0998 * <code>offset</code>. The length of this sequence increases by 0999 * the length of the argument. 1000 * <p> 1001 * The overall effect is exactly as if the argument were converted to 1002 * a string by the method {@link String#valueOf(char[])} and the 1003 * characters of that string were then 1004 * {@link #insert(int,String) inserted} into this 1005 * character sequence at the position indicated by 1006 * <code>offset</code>. 1007 * 1008 * @param offset the offset. 1009 * @param str a character array. 1010 * @return a reference to this object. 1011 * @throws StringIndexOutOfBoundsException if the offset is invalid. 1012 */ 1013 public AbstractStringBuilder insert(int offset, char str[]) { 1014 if ((offset < 0) || (offset > length())) 1015 throw new StringIndexOutOfBoundsException(offset); 1016 int len = str.length; 1017 int newCount = count + len; 1018 if (newCount > value.length) 1019 expandCapacity(newCount); 1020 System.arraycopy(value, offset, value, offset + len, count - offset); 1021 System.arraycopy(str, 0, value, offset, len); 1022 count = newCount; 1023 return this; 1024 } 1025 1026 /*** 1027 * Inserts the specified <code>CharSequence</code> into this sequence. 1028 * <p> 1029 * The characters of the <code>CharSequence</code> argument are inserted, 1030 * in order, into this sequence at the indicated offset, moving up 1031 * any characters originally above that position and increasing the length 1032 * of this sequence by the length of the argument s. 1033 * <p> 1034 * The result of this method is exactly the same as if it were an 1035 * invocation of this object's insert(dstOffset, s, 0, s.length()) method. 1036 * 1037 * <p>If <code>s</code> is <code>null</code>, then the four characters 1038 * <code>"null"</code> are inserted into this sequence. 1039 * 1040 * @param dstOffset the offset. 1041 * @param s the sequence to be inserted 1042 * @return a reference to this object. 1043 * @throws IndexOutOfBoundsException if the offset is invalid. 1044 */ 1045 public AbstractStringBuilder insert(int dstOffset, CharSequence s) { 1046 if (s == null) 1047 s = "null"; 1048 if (s instanceof String) 1049 return this.insert(dstOffset, (String)s); 1050 return this.insert(dstOffset, s, 0, s.length()); 1051 } 1052 1053 /*** 1054 * Inserts a subsequence of the specified <code>CharSequence</code> into 1055 * this sequence. 1056 * <p> 1057 * The subsequence of the argument <code>s</code> specified by 1058 * <code>start</code> and <code>end</code> are inserted, 1059 * in order, into this sequence at the specified destination offset, moving 1060 * up any characters originally above that position. The length of this 1061 * sequence is increased by <code>end - start</code>. 1062 * <p> 1063 * The character at index <i>k</i> in this sequence becomes equal to: 1064 * <ul> 1065 * <li>the character at index <i>k</i> in this sequence, if 1066 * <i>k</i> is less than <code>dstOffset</code> 1067 * <li>the character at index <i>k</i><code>+start-dstOffset</code> in 1068 * the argument <code>s</code>, if <i>k</i> is greater than or equal to 1069 * <code>dstOffset</code> but is less than <code>dstOffset+end-start</code> 1070 * <li>the character at index <i>k</i><code>-(end-start)</code> in this 1071 * sequence, if <i>k</i> is greater than or equal to 1072 * <code>dstOffset+end-start</code> 1073 * </ul><p> 1074 * The dstOffset argument must be greater than or equal to 1075 * <code>0</code>, and less than or equal to the length of this 1076 * sequence. 1077 * <p>The start argument must be nonnegative, and not greater than 1078 * <code>end</code>. 1079 * <p>The end argument must be greater than or equal to 1080 * <code>start</code>, and less than or equal to the length of s. 1081 * 1082 * <p>If <code>s</code> is <code>null</code>, then this method inserts 1083 * characters as if the s parameter was a sequence containing the four 1084 * characters <code>"null"</code>. 1085 * 1086 * @param dstOffset the offset in this sequence. 1087 * @param s the sequence to be inserted. 1088 * @param start the starting index of the subsequence to be inserted. 1089 * @param end the end index of the subsequence to be inserted. 1090 * @return a reference to this object. 1091 * @throws IndexOutOfBoundsException if <code>dstOffset</code> 1092 * is negative or greater than <code>this.length()</code>, or 1093 * <code>start</code> or <code>end</code> are negative, or 1094 * <code>start</code> is greater than <code>end</code> or 1095 * <code>end</code> is greater than <code>s.length()</code> 1096 */ 1097 public AbstractStringBuilder insert(int dstOffset, CharSequence s, 1098 int start, int end) { 1099 if (s == null) 1100 s = "null"; 1101 if ((dstOffset < 0) || (dstOffset > this.length())) 1102 throw new IndexOutOfBoundsException("dstOffset "+dstOffset); 1103 if ((start < 0) || (end < 0) || (start > end) || (end > s.length())) 1104 throw new IndexOutOfBoundsException( 1105 "start " + start + ", end " + end + ", s.length() " 1106 + s.length()); 1107 int len = end - start; 1108 if (len == 0) 1109 return this; 1110 int newCount = count + len; 1111 if (newCount > value.length) 1112 expandCapacity(newCount); 1113 System.arraycopy(value, dstOffset, value, dstOffset + len, 1114 count - dstOffset); 1115 for (int i=start; i<end; i++) 1116 value[dstOffset++] = s.charAt(i); 1117 count = newCount; 1118 return this; 1119 } 1120 1121 /*** 1122 * Inserts the string representation of the <code>boolean</code> 1123 * argument into this sequence. 1124 * <p> 1125 * The second argument is converted to a string as if by the method 1126 * <code>String.valueOf</code>, and the characters of that 1127 * string are then inserted into this sequence at the indicated 1128 * offset. 1129 * <p> 1130 * The offset argument must be greater than or equal to 1131 * <code>0</code>, and less than or equal to the length of this 1132 * sequence. 1133 * 1134 * @param offset the offset. 1135 * @param b a <code>boolean</code>. 1136 * @return a reference to this object. 1137 * @throws StringIndexOutOfBoundsException if the offset is invalid. 1138 */ 1139 public AbstractStringBuilder insert(int offset, boolean b) { 1140 return insert(offset, String.valueOf(b)); 1141 } 1142 1143 /*** 1144 * Inserts the string representation of the <code>char</code> 1145 * argument into this sequence. 1146 * <p> 1147 * The second argument is inserted into the contents of this sequence 1148 * at the position indicated by <code>offset</code>. The length 1149 * of this sequence increases by one. 1150 * <p> 1151 * The overall effect is exactly as if the argument were converted to 1152 * a string by the method {@link String#valueOf(char)} and the character 1153 * in that string were then {@link #insert(int, String) inserted} into 1154 * this character sequence at the position indicated by 1155 * <code>offset</code>. 1156 * <p> 1157 * The offset argument must be greater than or equal to 1158 * <code>0</code>, and less than or equal to the length of this 1159 * sequence. 1160 * 1161 * @param offset the offset. 1162 * @param c a <code>char</code>. 1163 * @return a reference to this object. 1164 * @throws IndexOutOfBoundsException if the offset is invalid. 1165 */ 1166 public AbstractStringBuilder insert(int offset, char c) { 1167 int newCount = count + 1; 1168 if (newCount > value.length) 1169 expandCapacity(newCount); 1170 System.arraycopy(value, offset, value, offset + 1, count - offset); 1171 value[offset] = c; 1172 count = newCount; 1173 return this; 1174 } 1175 1176 /*** 1177 * Inserts the string representation of the second <code>int</code> 1178 * argument into this sequence. 1179 * <p> 1180 * The second argument is converted to a string as if by the method 1181 * <code>String.valueOf</code>, and the characters of that 1182 * string are then inserted into this sequence at the indicated 1183 * offset. 1184 * <p> 1185 * The offset argument must be greater than or equal to 1186 * <code>0</code>, and less than or equal to the length of this 1187 * sequence. 1188 * 1189 * @param offset the offset. 1190 * @param i an <code>int</code>. 1191 * @return a reference to this object. 1192 * @throws StringIndexOutOfBoundsException if the offset is invalid. 1193 */ 1194 public AbstractStringBuilder insert(int offset, int i) { 1195 return insert(offset, String.valueOf(i)); 1196 } 1197 1198 /*** 1199 * Inserts the string representation of the <code>long</code> 1200 * argument into this sequence. 1201 * <p> 1202 * The second argument is converted to a string as if by the method 1203 * <code>String.valueOf</code>, and the characters of that 1204 * string are then inserted into this sequence at the position 1205 * indicated by <code>offset</code>. 1206 * <p> 1207 * The offset argument must be greater than or equal to 1208 * <code>0</code>, and less than or equal to the length of this 1209 * sequence. 1210 * 1211 * @param offset the offset. 1212 * @param l a <code>long</code>. 1213 * @return a reference to this object. 1214 * @throws StringIndexOutOfBoundsException if the offset is invalid. 1215 */ 1216 public AbstractStringBuilder insert(int offset, long l) { 1217 return insert(offset, String.valueOf(l)); 1218 } 1219 1220 /*** 1221 * Inserts the string representation of the <code>float</code> 1222 * argument into this sequence. 1223 * <p> 1224 * The second argument is converted to a string as if by the method 1225 * <code>String.valueOf</code>, and the characters of that 1226 * string are then inserted into this sequence at the indicated 1227 * offset. 1228 * <p> 1229 * The offset argument must be greater than or equal to 1230 * <code>0</code>, and less than or equal to the length of this 1231 * sequence. 1232 * 1233 * @param offset the offset. 1234 * @param f a <code>float</code>. 1235 * @return a reference to this object. 1236 * @throws StringIndexOutOfBoundsException if the offset is invalid. 1237 */ 1238 public AbstractStringBuilder insert(int offset, float f) { 1239 return insert(offset, String.valueOf(f)); 1240 } 1241 1242 /*** 1243 * Inserts the string representation of the <code>double</code> 1244 * argument into this sequence. 1245 * <p> 1246 * The second argument is converted to a string as if by the method 1247 * <code>String.valueOf</code>, and the characters of that 1248 * string are then inserted into this sequence at the indicated 1249 * offset. 1250 * <p> 1251 * The offset argument must be greater than or equal to 1252 * <code>0</code>, and less than or equal to the length of this 1253 * sequence. 1254 * 1255 * @param offset the offset. 1256 * @param d a <code>double</code>. 1257 * @return a reference to this object. 1258 * @throws StringIndexOutOfBoundsException if the offset is invalid. 1259 */ 1260 public AbstractStringBuilder insert(int offset, double d) { 1261 return insert(offset, String.valueOf(d)); 1262 } 1263 1264 /*** 1265 * Returns the index within this string of the first occurrence of the 1266 * specified substring. The integer returned is the smallest value 1267 * <i>k</i> such that: 1268 * <blockquote><pre> 1269 * this.toString().startsWith(str, <i>k</i>) 1270 * </pre></blockquote> 1271 * is <code>true</code>. 1272 * 1273 * @param str any string. 1274 * @return if the string argument occurs as a substring within this 1275 * object, then the index of the first character of the first 1276 * such substring is returned; if it does not occur as a 1277 * substring, <code>-1</code> is returned. 1278 * @throws java.lang.NullPointerException if <code>str</code> is 1279 * <code>null</code>. 1280 */ 1281 public int indexOf(String str) { 1282 return indexOf(str, 0); 1283 } 1284 1285 /*** 1286 * Returns the index within this string of the first occurrence of the 1287 * specified substring, starting at the specified index. The integer 1288 * returned is the smallest value <tt>k</tt> for which: 1289 * <blockquote><pre> 1290 * k >= Math.min(fromIndex, str.length()) && 1291 * this.toString().startsWith(str, k) 1292 * </pre></blockquote> 1293 * If no such value of <i>k</i> exists, then -1 is returned. 1294 * 1295 * @param str the substring for which to search. 1296 * @param fromIndex the index from which to start the search. 1297 * @return the index within this string of the first occurrence of the 1298 * specified substring, starting at the specified index. 1299 * @throws java.lang.NullPointerException if <code>str</code> is 1300 * <code>null</code>. 1301 */ 1302 public int indexOf(String str, int fromIndex) { 1303 return String.indexOf(value, 0, count, 1304 str.toCharArray(), 0, str.length(), fromIndex); 1305 } 1306 1307 /*** 1308 * Returns the index within this string of the rightmost occurrence 1309 * of the specified substring. The rightmost empty string "" is 1310 * considered to occur at the index value <code>this.length()</code>. 1311 * The returned index is the largest value <i>k</i> such that 1312 * <blockquote><pre> 1313 * this.toString().startsWith(str, k) 1314 * </pre></blockquote> 1315 * is true. 1316 * 1317 * @param str the substring to search for. 1318 * @return if the string argument occurs one or more times as a substring 1319 * within this object, then the index of the first character of 1320 * the last such substring is returned. If it does not occur as 1321 * a substring, <code>-1</code> is returned. 1322 * @throws java.lang.NullPointerException if <code>str</code> is 1323 * <code>null</code>. 1324 */ 1325 public int lastIndexOf(String str) { 1326 return lastIndexOf(str, count); 1327 } 1328 1329 /*** 1330 * Returns the index within this string of the last occurrence of the 1331 * specified substring. The integer returned is the largest value <i>k</i> 1332 * such that: 1333 * <blockquote><pre> 1334 * k <= Math.min(fromIndex, str.length()) && 1335 * this.toString().startsWith(str, k) 1336 * </pre></blockquote> 1337 * If no such value of <i>k</i> exists, then -1 is returned. 1338 * 1339 * @param str the substring to search for. 1340 * @param fromIndex the index to start the search from. 1341 * @return the index within this sequence of the last occurrence of the 1342 * specified substring. 1343 * @throws java.lang.NullPointerException if <code>str</code> is 1344 * <code>null</code>. 1345 */ 1346 public int lastIndexOf(String str, int fromIndex) { 1347 return String.lastIndexOf(value, 0, count, 1348 str.toCharArray(), 0, str.length(), fromIndex); 1349 } 1350 1351 /*** 1352 * Causes this character sequence to be replaced by the reverse of 1353 * the sequence. If there are any surrogate pairs included in the 1354 * sequence, these are treated as single characters for the 1355 * reverse operation. Thus, the order of the high-low surrogates 1356 * is never reversed. 1357 * 1358 * Let <i>n</i> be the character length of this character sequence 1359 * (not the length in <code>char</code> values) just prior to 1360 * execution of the <code>reverse</code> method. Then the 1361 * character at index <i>k</i> in the new character sequence is 1362 * equal to the character at index <i>n-k-1</i> in the old 1363 * character sequence. 1364 * 1365 * <p>Note that the reverse operation may result in producing 1366 * surrogate pairs that were unpaired low-surrogates and 1367 * high-surrogates before the operation. For example, reversing 1368 * "\uDC00\uD800" produces "\uD800\uDC00" which is 1369 * a valid surrogate pair. 1370 * 1371 * @return a reference to this object. 1372 */ 1373 public AbstractStringBuilder reverse() { 1374 boolean hasSurrogate = false; 1375 int n = count - 1; 1376 for (int j = (n-1) >> 1; j >= 0; --j) { 1377 char temp = value[j]; 1378 char temp2 = value[n - j]; 1379 if (!hasSurrogate) { 1380 hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE) 1381 || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE); 1382 } 1383 value[j] = temp2; 1384 value[n - j] = temp; 1385 } 1386 if (hasSurrogate) { 1387 // Reverse back all valid surrogate pairs 1388 for (int i = 0; i < count - 1; i++) { 1389 char c2 = value[i]; 1390 if (Character.isLowSurrogate(c2)) { 1391 char c1 = value[i + 1]; 1392 if (Character.isHighSurrogate(c1)) { 1393 value[i++] = c1; 1394 value[i] = c2; 1395 } 1396 } 1397 } 1398 } 1399 return this; 1400 } 1401 1402 /*** 1403 * Returns a string representing the data in this sequence. 1404 * A new <code>String</code> object is allocated and initialized to 1405 * contain the character sequence currently represented by this 1406 * object. This <code>String</code> is then returned. Subsequent 1407 * changes to this sequence do not affect the contents of the 1408 * <code>String</code>. 1409 * 1410 * @return a string representation of this sequence of characters. 1411 */ 1412 public abstract String toString(); 1413 1414 /*** 1415 * Needed by <tt>String</tt> for the contentEquals method. 1416 */ 1417 final char[] getValue() { 1418 return value; 1419 } 1420 1421 }