GNU Classpath (0.17) | ||
Frames | No Frames |
1: /* StringBuilder.java -- Unsynchronized growable strings 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 3: Free Software Foundation, Inc. 4: 5: This file is part of GNU Classpath. 6: 7: GNU Classpath is free software; you can redistribute it and/or modify 8: it under the terms of the GNU General Public License as published by 9: the Free Software Foundation; either version 2, or (at your option) 10: any later version. 11: 12: GNU Classpath is distributed in the hope that it will be useful, but 13: WITHOUT ANY WARRANTY; without even the implied warranty of 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15: General Public License for more details. 16: 17: You should have received a copy of the GNU General Public License 18: along with GNU Classpath; see the file COPYING. If not, write to the 19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20: 02110-1301 USA. 21: 22: Linking this library statically or dynamically with other modules is 23: making a combined work based on this library. Thus, the terms and 24: conditions of the GNU General Public License cover the whole 25: combination. 26: 27: As a special exception, the copyright holders of this library give you 28: permission to link this library with independent modules to produce an 29: executable, regardless of the license terms of these independent 30: modules, and to copy and distribute the resulting executable under 31: terms of your choice, provided that you also meet, for each linked 32: independent module, the terms and conditions of the license of that 33: module. An independent module is a module which is not derived from 34: or based on this library. If you modify this library, you may extend 35: this exception to your version of the library, but you are not 36: obligated to do so. If you do not wish to do so, delete this 37: exception statement from your version. */ 38: 39: package java.lang; 40: 41: import java.io.Serializable; 42: 43: /** 44: * <code>StringBuilder</code> represents a changeable <code>String</code>. 45: * It provides the operations required to modify the 46: * <code>StringBuilder</code>, including insert, replace, delete, append, 47: * and reverse. It like <code>StringBuffer</code>, but is not 48: * synchronized. It is ideal for use when it is known that the 49: * object will only be used from a single thread. 50: * 51: * <p><code>StringBuilder</code>s are variable-length in nature, so even if 52: * you initialize them to a certain size, they can still grow larger than 53: * that. <em>Capacity</em> indicates the number of characters the 54: * <code>StringBuilder</code> can have in it before it has to grow (growing 55: * the char array is an expensive operation involving <code>new</code>). 56: * 57: * <p>Incidentally, compilers often implement the String operator "+" 58: * by using a <code>StringBuilder</code> operation:<br> 59: * <code>a + b</code><br> 60: * is the same as<br> 61: * <code>new StringBuilder().append(a).append(b).toString()</code>. 62: * 63: * <p>Classpath's StringBuilder is capable of sharing memory with Strings for 64: * efficiency. This will help when a StringBuilder is converted to a String 65: * and the StringBuilder is not changed after that (quite common when 66: * performing string concatenation). 67: * 68: * @author Paul Fisher 69: * @author John Keiser 70: * @author Tom Tromey 71: * @author Eric Blake (ebb9@email.byu.edu) 72: * @see String 73: * @see StringBuffer 74: * 75: * @since 1.5 76: */ 77: // FIX15: Implement Appendable when co-variant methods are available 78: public final class StringBuilder 79: implements Serializable, CharSequence 80: { 81: // Implementation note: if you change this class, you usually will 82: // want to change StringBuffer as well. 83: 84: /** 85: * For compatability with Sun's JDK 86: */ 87: private static final long serialVersionUID = 4383685877147921099L; 88: 89: /** 90: * Index of next available character (and thus the size of the current 91: * string contents). Note that this has permissions set this way so that 92: * String can get the value. 93: * 94: * @serial the number of characters in the buffer 95: */ 96: int count; 97: 98: /** 99: * The buffer. Note that this has permissions set this way so that String 100: * can get the value. 101: * 102: * @serial the buffer 103: */ 104: char[] value; 105: 106: /** 107: * The default capacity of a buffer. 108: */ 109: private static final int DEFAULT_CAPACITY = 16; 110: 111: /** 112: * Create a new StringBuilder with default capacity 16. 113: */ 114: public StringBuilder() 115: { 116: this(DEFAULT_CAPACITY); 117: } 118: 119: /** 120: * Create an empty <code>StringBuilder</code> with the specified initial 121: * capacity. 122: * 123: * @param capacity the initial capacity 124: * @throws NegativeArraySizeException if capacity is negative 125: */ 126: public StringBuilder(int capacity) 127: { 128: value = new char[capacity]; 129: } 130: 131: /** 132: * Create a new <code>StringBuilder</code> with the characters in the 133: * specified <code>String</code>. Initial capacity will be the size of the 134: * String plus 16. 135: * 136: * @param str the <code>String</code> to convert 137: * @throws NullPointerException if str is null 138: */ 139: public StringBuilder(String str) 140: { 141: // Unfortunately, because the size is 16 larger, we cannot share. 142: count = str.count; 143: value = new char[count + DEFAULT_CAPACITY]; 144: str.getChars(0, count, value, 0); 145: } 146: 147: /** 148: * Create a new <code>StringBuilder</code> with the characters in the 149: * specified <code>CharSequence</code>. Initial capacity will be the 150: * length of the sequence plus 16; if the sequence reports a length 151: * less than or equal to 0, then the initial capacity will be 16. 152: * 153: * @param seq the initializing <code>CharSequence</code> 154: * @throws NullPointerException if str is null 155: */ 156: public StringBuilder(CharSequence seq) 157: { 158: int len = seq.length(); 159: count = len <= 0 ? 0 : len; 160: value = new char[count + DEFAULT_CAPACITY]; 161: for (int i = 0; i < len; ++i) 162: value[i] = seq.charAt(i); 163: } 164: 165: /** 166: * Get the length of the <code>String</code> this <code>StringBuilder</code> 167: * would create. Not to be confused with the <em>capacity</em> of the 168: * <code>StringBuilder</code>. 169: * 170: * @return the length of this <code>StringBuilder</code> 171: * @see #capacity() 172: * @see #setLength(int) 173: */ 174: public int length() 175: { 176: return count; 177: } 178: 179: /** 180: * Get the total number of characters this <code>StringBuilder</code> can 181: * support before it must be grown. Not to be confused with <em>length</em>. 182: * 183: * @return the capacity of this <code>StringBuilder</code> 184: * @see #length() 185: * @see #ensureCapacity(int) 186: */ 187: public int capacity() 188: { 189: return value.length; 190: } 191: 192: /** 193: * Increase the capacity of this <code>StringBuilder</code>. This will 194: * ensure that an expensive growing operation will not occur until 195: * <code>minimumCapacity</code> is reached. The buffer is grown to the 196: * larger of <code>minimumCapacity</code> and 197: * <code>capacity() * 2 + 2</code>, if it is not already large enough. 198: * 199: * @param minimumCapacity the new capacity 200: * @see #capacity() 201: */ 202: public void ensureCapacity(int minimumCapacity) 203: { 204: if (minimumCapacity > value.length) 205: { 206: int max = value.length * 2 + 2; 207: minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); 208: char[] nb = new char[minimumCapacity]; 209: System.arraycopy(value, 0, nb, 0, count); 210: value = nb; 211: } 212: } 213: 214: /** 215: * Set the length of this StringBuilder. If the new length is greater than 216: * the current length, all the new characters are set to '\0'. If the new 217: * length is less than the current length, the first <code>newLength</code> 218: * characters of the old array will be preserved, and the remaining 219: * characters are truncated. 220: * 221: * @param newLength the new length 222: * @throws IndexOutOfBoundsException if the new length is negative 223: * (while unspecified, this is a StringIndexOutOfBoundsException) 224: * @see #length() 225: */ 226: public void setLength(int newLength) 227: { 228: if (newLength < 0) 229: throw new StringIndexOutOfBoundsException(newLength); 230: 231: int valueLength = value.length; 232: 233: /* Always call ensureCapacity in order to preserve copy-on-write 234: semantics. */ 235: ensureCapacity(newLength); 236: 237: if (newLength < valueLength) 238: { 239: /* If the StringBuilder's value just grew, then we know that 240: value is newly allocated and the region between count and 241: newLength is filled with '\0'. */ 242: count = newLength; 243: } 244: else 245: { 246: /* The StringBuilder's value doesn't need to grow. However, 247: we should clear out any cruft that may exist. */ 248: while (count < newLength) 249: value[count++] = '\0'; 250: } 251: } 252: 253: /** 254: * Get the character at the specified index. 255: * 256: * @param index the index of the character to get, starting at 0 257: * @return the character at the specified index 258: * @throws IndexOutOfBoundsException if index is negative or >= length() 259: * (while unspecified, this is a StringIndexOutOfBoundsException) 260: */ 261: public char charAt(int index) 262: { 263: if (index < 0 || index >= count) 264: throw new StringIndexOutOfBoundsException(index); 265: return value[index]; 266: } 267: 268: /** 269: * Get the specified array of characters. <code>srcOffset - srcEnd</code> 270: * characters will be copied into the array you pass in. 271: * 272: * @param srcOffset the index to start copying from (inclusive) 273: * @param srcEnd the index to stop copying from (exclusive) 274: * @param dst the array to copy into 275: * @param dstOffset the index to start copying into 276: * @throws NullPointerException if dst is null 277: * @throws IndexOutOfBoundsException if any source or target indices are 278: * out of range (while unspecified, source problems cause a 279: * StringIndexOutOfBoundsException, and dest problems cause an 280: * ArrayIndexOutOfBoundsException) 281: * @see System#arraycopy(Object, int, Object, int, int) 282: */ 283: public void getChars(int srcOffset, int srcEnd, 284: char[] dst, int dstOffset) 285: { 286: if (srcOffset < 0 || srcEnd > count || srcEnd < srcOffset) 287: throw new StringIndexOutOfBoundsException(); 288: System.arraycopy(value, srcOffset, dst, dstOffset, srcEnd - srcOffset); 289: } 290: 291: /** 292: * Set the character at the specified index. 293: * 294: * @param index the index of the character to set starting at 0 295: * @param ch the value to set that character to 296: * @throws IndexOutOfBoundsException if index is negative or >= length() 297: * (while unspecified, this is a StringIndexOutOfBoundsException) 298: */ 299: public void setCharAt(int index, char ch) 300: { 301: if (index < 0 || index >= count) 302: throw new StringIndexOutOfBoundsException(index); 303: // Call ensureCapacity to enforce copy-on-write. 304: ensureCapacity(count); 305: value[index] = ch; 306: } 307: 308: /** 309: * Append the <code>String</code> value of the argument to this 310: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 311: * to <code>String</code>. 312: * 313: * @param obj the <code>Object</code> to convert and append 314: * @return this <code>StringBuilder</code> 315: * @see String#valueOf(Object) 316: * @see #append(String) 317: */ 318: public StringBuilder append(Object obj) 319: { 320: return append(obj == null ? "null" : obj.toString()); 321: } 322: 323: /** 324: * Append the <code>String</code> to this <code>StringBuilder</code>. If 325: * str is null, the String "null" is appended. 326: * 327: * @param str the <code>String</code> to append 328: * @return this <code>StringBuilder</code> 329: */ 330: public StringBuilder append(String str) 331: { 332: if (str == null) 333: str = "null"; 334: int len = str.count; 335: ensureCapacity(count + len); 336: str.getChars(0, len, value, count); 337: count += len; 338: return this; 339: } 340: 341: /** 342: * Append the <code>StringBuilder</code> value of the argument to this 343: * <code>StringBuilder</code>. This behaves the same as 344: * <code>append((Object) stringBuffer)</code>, except it is more efficient. 345: * 346: * @param stringBuffer the <code>StringBuilder</code> to convert and append 347: * @return this <code>StringBuilder</code> 348: * @see #append(Object) 349: */ 350: public StringBuilder append(StringBuffer stringBuffer) 351: { 352: if (stringBuffer == null) 353: return append("null"); 354: synchronized (stringBuffer) 355: { 356: int len = stringBuffer.count; 357: ensureCapacity(count + len); 358: System.arraycopy(stringBuffer.value, 0, value, count, len); 359: count += len; 360: } 361: return this; 362: } 363: 364: /** 365: * Append the <code>char</code> array to this <code>StringBuilder</code>. 366: * This is similar (but more efficient) than 367: * <code>append(new String(data))</code>, except in the case of null. 368: * 369: * @param data the <code>char[]</code> to append 370: * @return this <code>StringBuilder</code> 371: * @throws NullPointerException if <code>str</code> is <code>null</code> 372: * @see #append(char[], int, int) 373: */ 374: public StringBuilder append(char[] data) 375: { 376: return append(data, 0, data.length); 377: } 378: 379: /** 380: * Append part of the <code>char</code> array to this 381: * <code>StringBuilder</code>. This is similar (but more efficient) than 382: * <code>append(new String(data, offset, count))</code>, except in the case 383: * of null. 384: * 385: * @param data the <code>char[]</code> to append 386: * @param offset the start location in <code>str</code> 387: * @param count the number of characters to get from <code>str</code> 388: * @return this <code>StringBuilder</code> 389: * @throws NullPointerException if <code>str</code> is <code>null</code> 390: * @throws IndexOutOfBoundsException if offset or count is out of range 391: * (while unspecified, this is a StringIndexOutOfBoundsException) 392: */ 393: public StringBuilder append(char[] data, int offset, int count) 394: { 395: if (offset < 0 || count < 0 || offset > data.length - count) 396: throw new StringIndexOutOfBoundsException(); 397: ensureCapacity(this.count + count); 398: System.arraycopy(data, offset, value, this.count, count); 399: this.count += count; 400: return this; 401: } 402: 403: /** 404: * Append the <code>String</code> value of the argument to this 405: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 406: * to <code>String</code>. 407: * 408: * @param bool the <code>boolean</code> to convert and append 409: * @return this <code>StringBuilder</code> 410: * @see String#valueOf(boolean) 411: */ 412: public StringBuilder append(boolean bool) 413: { 414: return append(bool ? "true" : "false"); 415: } 416: 417: /** 418: * Append the <code>char</code> to this <code>StringBuilder</code>. 419: * 420: * @param ch the <code>char</code> to append 421: * @return this <code>StringBuilder</code> 422: */ 423: public StringBuilder append(char ch) 424: { 425: ensureCapacity(count + 1); 426: value[count++] = ch; 427: return this; 428: } 429: 430: /** 431: * Append the characters in the <code>CharSequence</code> to this 432: * buffer. 433: * 434: * @param seq the <code>CharSequence</code> providing the characters 435: * @return this <code>StringBuilder</code> 436: */ 437: public StringBuilder append(CharSequence seq) 438: { 439: return append(seq, 0, seq.length()); 440: } 441: 442: /** 443: * Append some characters from the <code>CharSequence</code> to this 444: * buffer. If the argument is null, the four characters "null" are 445: * appended. 446: * 447: * @param seq the <code>CharSequence</code> providing the characters 448: * @param start the starting index 449: * @param end one past the final index 450: * @return this <code>StringBuilder</code> 451: */ 452: public StringBuilder append(CharSequence seq, int start, 453: int end) 454: { 455: if (seq == null) 456: return append("null"); 457: if (end - start > 0) 458: { 459: ensureCapacity(count + end - start); 460: for (; start < end; ++start) 461: value[count++] = seq.charAt(start); 462: } 463: return this; 464: } 465: 466: /** 467: * Append the <code>String</code> value of the argument to this 468: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 469: * to <code>String</code>. 470: * 471: * @param inum the <code>int</code> to convert and append 472: * @return this <code>StringBuilder</code> 473: * @see String#valueOf(int) 474: */ 475: // This is native in libgcj, for efficiency. 476: public StringBuilder append(int inum) 477: { 478: return append(String.valueOf(inum)); 479: } 480: 481: /** 482: * Append the <code>String</code> value of the argument to this 483: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 484: * to <code>String</code>. 485: * 486: * @param lnum the <code>long</code> to convert and append 487: * @return this <code>StringBuilder</code> 488: * @see String#valueOf(long) 489: */ 490: public StringBuilder append(long lnum) 491: { 492: return append(Long.toString(lnum, 10)); 493: } 494: 495: /** 496: * Append the <code>String</code> value of the argument to this 497: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 498: * to <code>String</code>. 499: * 500: * @param fnum the <code>float</code> to convert and append 501: * @return this <code>StringBuilder</code> 502: * @see String#valueOf(float) 503: */ 504: public StringBuilder append(float fnum) 505: { 506: return append(Float.toString(fnum)); 507: } 508: 509: /** 510: * Append the <code>String</code> value of the argument to this 511: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 512: * to <code>String</code>. 513: * 514: * @param dnum the <code>double</code> to convert and append 515: * @return this <code>StringBuilder</code> 516: * @see String#valueOf(double) 517: */ 518: public StringBuilder append(double dnum) 519: { 520: return append(Double.toString(dnum)); 521: } 522: 523: /** 524: * Delete characters from this <code>StringBuilder</code>. 525: * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is 526: * harmless for end to be larger than length(). 527: * 528: * @param start the first character to delete 529: * @param end the index after the last character to delete 530: * @return this <code>StringBuilder</code> 531: * @throws StringIndexOutOfBoundsException if start or end are out of bounds 532: */ 533: public StringBuilder delete(int start, int end) 534: { 535: if (start < 0 || start > count || start > end) 536: throw new StringIndexOutOfBoundsException(start); 537: if (end > count) 538: end = count; 539: // This will unshare if required. 540: ensureCapacity(count); 541: if (count - end != 0) 542: System.arraycopy(value, end, value, start, count - end); 543: count -= end - start; 544: return this; 545: } 546: 547: /** 548: * Delete a character from this <code>StringBuilder</code>. 549: * 550: * @param index the index of the character to delete 551: * @return this <code>StringBuilder</code> 552: * @throws StringIndexOutOfBoundsException if index is out of bounds 553: */ 554: public StringBuilder deleteCharAt(int index) 555: { 556: return delete(index, index + 1); 557: } 558: 559: /** 560: * Replace characters between index <code>start</code> (inclusive) and 561: * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code> 562: * is larger than the size of this StringBuilder, all characters after 563: * <code>start</code> are replaced. 564: * 565: * @param start the beginning index of characters to delete (inclusive) 566: * @param end the ending index of characters to delete (exclusive) 567: * @param str the new <code>String</code> to insert 568: * @return this <code>StringBuilder</code> 569: * @throws StringIndexOutOfBoundsException if start or end are out of bounds 570: * @throws NullPointerException if str is null 571: */ 572: public StringBuilder replace(int start, int end, String str) 573: { 574: if (start < 0 || start > count || start > end) 575: throw new StringIndexOutOfBoundsException(start); 576: 577: int len = str.count; 578: // Calculate the difference in 'count' after the replace. 579: int delta = len - (end > count ? count : end) + start; 580: ensureCapacity(count + delta); 581: 582: if (delta != 0 && end < count) 583: System.arraycopy(value, end, value, end + delta, count - end); 584: 585: str.getChars(0, len, value, start); 586: count += delta; 587: return this; 588: } 589: 590: /** 591: * Creates a substring of this StringBuilder, starting at a specified index 592: * and ending at the end of this StringBuilder. 593: * 594: * @param beginIndex index to start substring (base 0) 595: * @return new String which is a substring of this StringBuilder 596: * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds 597: * @see #substring(int, int) 598: */ 599: public String substring(int beginIndex) 600: { 601: return substring(beginIndex, count); 602: } 603: 604: /** 605: * Creates a substring of this StringBuilder, starting at a specified index 606: * and ending at one character before a specified index. This is implemented 607: * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy 608: * the CharSequence interface. 609: * 610: * @param beginIndex index to start at (inclusive, base 0) 611: * @param endIndex index to end at (exclusive) 612: * @return new String which is a substring of this StringBuilder 613: * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of 614: * bounds 615: * @see #substring(int, int) 616: */ 617: public CharSequence subSequence(int beginIndex, int endIndex) 618: { 619: return substring(beginIndex, endIndex); 620: } 621: 622: /** 623: * Creates a substring of this StringBuilder, starting at a specified index 624: * and ending at one character before a specified index. 625: * 626: * @param beginIndex index to start at (inclusive, base 0) 627: * @param endIndex index to end at (exclusive) 628: * @return new String which is a substring of this StringBuilder 629: * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out 630: * of bounds 631: */ 632: public String substring(int beginIndex, int endIndex) 633: { 634: int len = endIndex - beginIndex; 635: if (beginIndex < 0 || endIndex > count || endIndex < beginIndex) 636: throw new StringIndexOutOfBoundsException(); 637: if (len == 0) 638: return ""; 639: return new String(value, beginIndex, len); 640: } 641: 642: /** 643: * Insert a subarray of the <code>char[]</code> argument into this 644: * <code>StringBuilder</code>. 645: * 646: * @param offset the place to insert in this buffer 647: * @param str the <code>char[]</code> to insert 648: * @param str_offset the index in <code>str</code> to start inserting from 649: * @param len the number of characters to insert 650: * @return this <code>StringBuilder</code> 651: * @throws NullPointerException if <code>str</code> is <code>null</code> 652: * @throws StringIndexOutOfBoundsException if any index is out of bounds 653: */ 654: public StringBuilder insert(int offset, 655: char[] str, int str_offset, int len) 656: { 657: if (offset < 0 || offset > count || len < 0 658: || str_offset < 0 || str_offset > str.length - len) 659: throw new StringIndexOutOfBoundsException(); 660: ensureCapacity(count + len); 661: System.arraycopy(value, offset, value, offset + len, count - offset); 662: System.arraycopy(str, str_offset, value, offset, len); 663: count += len; 664: return this; 665: } 666: 667: /** 668: * Insert the <code>String</code> value of the argument into this 669: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 670: * to <code>String</code>. 671: * 672: * @param offset the place to insert in this buffer 673: * @param obj the <code>Object</code> to convert and insert 674: * @return this <code>StringBuilder</code> 675: * @exception StringIndexOutOfBoundsException if offset is out of bounds 676: * @see String#valueOf(Object) 677: */ 678: public StringBuilder insert(int offset, Object obj) 679: { 680: return insert(offset, obj == null ? "null" : obj.toString()); 681: } 682: 683: /** 684: * Insert the <code>String</code> argument into this 685: * <code>StringBuilder</code>. If str is null, the String "null" is used 686: * instead. 687: * 688: * @param offset the place to insert in this buffer 689: * @param str the <code>String</code> to insert 690: * @return this <code>StringBuilder</code> 691: * @throws StringIndexOutOfBoundsException if offset is out of bounds 692: */ 693: public StringBuilder insert(int offset, String str) 694: { 695: if (offset < 0 || offset > count) 696: throw new StringIndexOutOfBoundsException(offset); 697: if (str == null) 698: str = "null"; 699: int len = str.count; 700: ensureCapacity(count + len); 701: System.arraycopy(value, offset, value, offset + len, count - offset); 702: str.getChars(0, len, value, offset); 703: count += len; 704: return this; 705: } 706: 707: /** 708: * Insert the <code>char[]</code> argument into this 709: * <code>StringBuilder</code>. 710: * 711: * @param offset the place to insert in this buffer 712: * @param data the <code>char[]</code> to insert 713: * @return this <code>StringBuilder</code> 714: * @throws NullPointerException if <code>data</code> is <code>null</code> 715: * @throws StringIndexOutOfBoundsException if offset is out of bounds 716: * @see #insert(int, char[], int, int) 717: */ 718: public StringBuilder insert(int offset, char[] data) 719: { 720: return insert(offset, data, 0, data.length); 721: } 722: 723: /** 724: * Insert the <code>String</code> value of the argument into this 725: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 726: * to <code>String</code>. 727: * 728: * @param offset the place to insert in this buffer 729: * @param bool the <code>boolean</code> to convert and insert 730: * @return this <code>StringBuilder</code> 731: * @throws StringIndexOutOfBoundsException if offset is out of bounds 732: * @see String#valueOf(boolean) 733: */ 734: public StringBuilder insert(int offset, boolean bool) 735: { 736: return insert(offset, bool ? "true" : "false"); 737: } 738: 739: /** 740: * Insert the <code>char</code> argument into this <code>StringBuilder</code>. 741: * 742: * @param offset the place to insert in this buffer 743: * @param ch the <code>char</code> to insert 744: * @return this <code>StringBuilder</code> 745: * @throws StringIndexOutOfBoundsException if offset is out of bounds 746: */ 747: public StringBuilder insert(int offset, char ch) 748: { 749: if (offset < 0 || offset > count) 750: throw new StringIndexOutOfBoundsException(offset); 751: ensureCapacity(count + 1); 752: System.arraycopy(value, offset, value, offset + 1, count - offset); 753: value[offset] = ch; 754: count++; 755: return this; 756: } 757: 758: /** 759: * Insert the <code>String</code> value of the argument into this 760: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 761: * to <code>String</code>. 762: * 763: * @param offset the place to insert in this buffer 764: * @param inum the <code>int</code> to convert and insert 765: * @return this <code>StringBuilder</code> 766: * @throws StringIndexOutOfBoundsException if offset is out of bounds 767: * @see String#valueOf(int) 768: */ 769: public StringBuilder insert(int offset, int inum) 770: { 771: return insert(offset, String.valueOf(inum)); 772: } 773: 774: /** 775: * Insert the <code>String</code> value of the argument into this 776: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 777: * to <code>String</code>. 778: * 779: * @param offset the place to insert in this buffer 780: * @param lnum the <code>long</code> to convert and insert 781: * @return this <code>StringBuilder</code> 782: * @throws StringIndexOutOfBoundsException if offset is out of bounds 783: * @see String#valueOf(long) 784: */ 785: public StringBuilder insert(int offset, long lnum) 786: { 787: return insert(offset, Long.toString(lnum, 10)); 788: } 789: 790: /** 791: * Insert the <code>String</code> value of the argument into this 792: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 793: * to <code>String</code>. 794: * 795: * @param offset the place to insert in this buffer 796: * @param fnum the <code>float</code> to convert and insert 797: * @return this <code>StringBuilder</code> 798: * @throws StringIndexOutOfBoundsException if offset is out of bounds 799: * @see String#valueOf(float) 800: */ 801: public StringBuilder insert(int offset, float fnum) 802: { 803: return insert(offset, Float.toString(fnum)); 804: } 805: 806: /** 807: * Insert the <code>String</code> value of the argument into this 808: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 809: * to <code>String</code>. 810: * 811: * @param offset the place to insert in this buffer 812: * @param dnum the <code>double</code> to convert and insert 813: * @return this <code>StringBuilder</code> 814: * @throws StringIndexOutOfBoundsException if offset is out of bounds 815: * @see String#valueOf(double) 816: */ 817: public StringBuilder insert(int offset, double dnum) 818: { 819: return insert(offset, Double.toString(dnum)); 820: } 821: 822: /** 823: * Finds the first instance of a substring in this StringBuilder. 824: * 825: * @param str String to find 826: * @return location (base 0) of the String, or -1 if not found 827: * @throws NullPointerException if str is null 828: * @see #indexOf(String, int) 829: */ 830: public int indexOf(String str) 831: { 832: return indexOf(str, 0); 833: } 834: 835: /** 836: * Finds the first instance of a String in this StringBuilder, starting at 837: * a given index. If starting index is less than 0, the search starts at 838: * the beginning of this String. If the starting index is greater than the 839: * length of this String, or the substring is not found, -1 is returned. 840: * 841: * @param str String to find 842: * @param fromIndex index to start the search 843: * @return location (base 0) of the String, or -1 if not found 844: * @throws NullPointerException if str is null 845: */ 846: public int indexOf(String str, int fromIndex) 847: { 848: if (fromIndex < 0) 849: fromIndex = 0; 850: int limit = count - str.count; 851: for ( ; fromIndex <= limit; fromIndex++) 852: if (regionMatches(fromIndex, str)) 853: return fromIndex; 854: return -1; 855: } 856: 857: /** 858: * Finds the last instance of a substring in this StringBuilder. 859: * 860: * @param str String to find 861: * @return location (base 0) of the String, or -1 if not found 862: * @throws NullPointerException if str is null 863: * @see #lastIndexOf(String, int) 864: */ 865: public int lastIndexOf(String str) 866: { 867: return lastIndexOf(str, count - str.count); 868: } 869: 870: /** 871: * Finds the last instance of a String in this StringBuilder, starting at a 872: * given index. If starting index is greater than the maximum valid index, 873: * then the search begins at the end of this String. If the starting index 874: * is less than zero, or the substring is not found, -1 is returned. 875: * 876: * @param str String to find 877: * @param fromIndex index to start the search 878: * @return location (base 0) of the String, or -1 if not found 879: * @throws NullPointerException if str is null 880: */ 881: public int lastIndexOf(String str, int fromIndex) 882: { 883: fromIndex = Math.min(fromIndex, count - str.count); 884: for ( ; fromIndex >= 0; fromIndex--) 885: if (regionMatches(fromIndex, str)) 886: return fromIndex; 887: return -1; 888: } 889: 890: /** 891: * Reverse the characters in this StringBuilder. The same sequence of 892: * characters exists, but in the reverse index ordering. 893: * 894: * @return this <code>StringBuilder</code> 895: */ 896: public StringBuilder reverse() 897: { 898: // Call ensureCapacity to enforce copy-on-write. 899: ensureCapacity(count); 900: for (int i = count >> 1, j = count - i; --i >= 0; ++j) 901: { 902: char c = value[i]; 903: value[i] = value[j]; 904: value[j] = c; 905: } 906: return this; 907: } 908: 909: /** 910: * Convert this <code>StringBuilder</code> to a <code>String</code>. The 911: * String is composed of the characters currently in this StringBuilder. Note 912: * that the result is a copy, and that future modifications to this buffer 913: * do not affect the String. 914: * 915: * @return the characters in this StringBuilder 916: */ 917: public String toString() 918: { 919: return new String(this); 920: } 921: 922: /** 923: * Predicate which determines if a substring of this matches another String 924: * starting at a specified offset for each String and continuing for a 925: * specified length. This is more efficient than creating a String to call 926: * indexOf on. 927: * 928: * @param toffset index to start comparison at for this String 929: * @param other non-null String to compare to region of this 930: * @return true if regions match, false otherwise 931: * @see #indexOf(String, int) 932: * @see #lastIndexOf(String, int) 933: * @see String#regionMatches(boolean, int, String, int, int) 934: */ 935: private boolean regionMatches(int toffset, String other) 936: { 937: int len = other.count; 938: int index = other.offset; 939: while (--len >= 0) 940: if (value[toffset++] != other.value[index++]) 941: return false; 942: return true; 943: } 944: }
GNU Classpath (0.17) |