Frames | No Frames |
1: /* StringBuilder.java -- Unsynchronized growable strings 2: Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 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: public final class StringBuilder 78: extends AbstractStringBuffer 79: implements Serializable, CharSequence, Appendable 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: * Create a new StringBuilder with default capacity 16. 91: */ 92: public StringBuilder() 93: { 94: super(); 95: } 96: 97: /** 98: * Create an empty <code>StringBuilder</code> with the specified initial 99: * capacity. 100: * 101: * @param capacity the initial capacity 102: * @throws NegativeArraySizeException if capacity is negative 103: */ 104: public StringBuilder(int capacity) 105: { 106: super(capacity); 107: } 108: 109: /** 110: * Create a new <code>StringBuilder</code> with the characters in the 111: * specified <code>String</code>. Initial capacity will be the size of the 112: * String plus 16. 113: * 114: * @param str the <code>String</code> to convert 115: * @throws NullPointerException if str is null 116: */ 117: public StringBuilder(String str) 118: { 119: super(str); 120: } 121: 122: /** 123: * Create a new <code>StringBuilder</code> with the characters in the 124: * specified <code>CharSequence</code>. Initial capacity will be the 125: * length of the sequence plus 16; if the sequence reports a length 126: * less than or equal to 0, then the initial capacity will be 16. 127: * 128: * @param seq the initializing <code>CharSequence</code> 129: * @throws NullPointerException if str is null 130: */ 131: public StringBuilder(CharSequence seq) 132: { 133: super(seq); 134: } 135: 136: /** 137: * Get the length of the <code>String</code> this <code>StringBuilder</code> 138: * would create. Not to be confused with the <em>capacity</em> of the 139: * <code>StringBuilder</code>. 140: * 141: * @return the length of this <code>StringBuilder</code> 142: * @see #capacity() 143: * @see #setLength(int) 144: */ 145: public int length() 146: { 147: return count; 148: } 149: 150: /** 151: * Get the total number of characters this <code>StringBuilder</code> can 152: * support before it must be grown. Not to be confused with <em>length</em>. 153: * 154: * @return the capacity of this <code>StringBuilder</code> 155: * @see #length() 156: * @see #ensureCapacity(int) 157: */ 158: public int capacity() 159: { 160: return value.length; 161: } 162: 163: /** 164: * Append the <code>String</code> value of the argument to this 165: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 166: * to <code>String</code>. 167: * 168: * @param obj the <code>Object</code> to convert and append 169: * @return this <code>StringBuilder</code> 170: * @see String#valueOf(Object) 171: * @see #append(String) 172: */ 173: public StringBuilder append(Object obj) 174: { 175: super.append(obj); 176: return this; 177: } 178: 179: /** 180: * Append the <code>String</code> to this <code>StringBuilder</code>. If 181: * str is null, the String "null" is appended. 182: * 183: * @param str the <code>String</code> to append 184: * @return this <code>StringBuilder</code> 185: */ 186: public StringBuilder append(String str) 187: { 188: super.append(str); 189: return this; 190: } 191: 192: /** 193: * Append the <code>StringBuilder</code> value of the argument to this 194: * <code>StringBuilder</code>. This behaves the same as 195: * <code>append((Object) stringBuffer)</code>, except it is more efficient. 196: * 197: * @param stringBuffer the <code>StringBuilder</code> to convert and append 198: * @return this <code>StringBuilder</code> 199: * @see #append(Object) 200: */ 201: public StringBuilder append(StringBuffer stringBuffer) 202: { 203: super.append(stringBuffer); 204: return this; 205: } 206: 207: /** 208: * Append the <code>char</code> array to this <code>StringBuilder</code>. 209: * This is similar (but more efficient) than 210: * <code>append(new String(data))</code>, except in the case of null. 211: * 212: * @param data the <code>char[]</code> to append 213: * @return this <code>StringBuilder</code> 214: * @throws NullPointerException if <code>str</code> is <code>null</code> 215: * @see #append(char[], int, int) 216: */ 217: public StringBuilder append(char[] data) 218: { 219: super.append(data, 0, data.length); 220: return this; 221: } 222: 223: /** 224: * Append part of the <code>char</code> array to this 225: * <code>StringBuilder</code>. This is similar (but more efficient) than 226: * <code>append(new String(data, offset, count))</code>, except in the case 227: * of null. 228: * 229: * @param data the <code>char[]</code> to append 230: * @param offset the start location in <code>str</code> 231: * @param count the number of characters to get from <code>str</code> 232: * @return this <code>StringBuilder</code> 233: * @throws NullPointerException if <code>str</code> is <code>null</code> 234: * @throws IndexOutOfBoundsException if offset or count is out of range 235: * (while unspecified, this is a StringIndexOutOfBoundsException) 236: */ 237: public StringBuilder append(char[] data, int offset, int count) 238: { 239: super.append(data, offset, count); 240: return this; 241: } 242: 243: /** 244: * Append the <code>String</code> value of the argument to this 245: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 246: * to <code>String</code>. 247: * 248: * @param bool the <code>boolean</code> to convert and append 249: * @return this <code>StringBuilder</code> 250: * @see String#valueOf(boolean) 251: */ 252: public StringBuilder append(boolean bool) 253: { 254: super.append(bool); 255: return this; 256: } 257: 258: /** 259: * Append the <code>char</code> to this <code>StringBuilder</code>. 260: * 261: * @param ch the <code>char</code> to append 262: * @return this <code>StringBuilder</code> 263: */ 264: public StringBuilder append(char ch) 265: { 266: super.append(ch); 267: return this; 268: } 269: 270: /** 271: * Append the characters in the <code>CharSequence</code> to this 272: * buffer. 273: * 274: * @param seq the <code>CharSequence</code> providing the characters 275: * @return this <code>StringBuilder</code> 276: */ 277: public StringBuilder append(CharSequence seq) 278: { 279: super.append(seq, 0, seq.length()); 280: return this; 281: } 282: 283: /** 284: * Append some characters from the <code>CharSequence</code> to this 285: * buffer. If the argument is null, the four characters "null" are 286: * appended. 287: * 288: * @param seq the <code>CharSequence</code> providing the characters 289: * @param start the starting index 290: * @param end one past the final index 291: * @return this <code>StringBuilder</code> 292: */ 293: public StringBuilder append(CharSequence seq, int start, 294: int end) 295: { 296: super.append(seq, start, end); 297: return this; 298: } 299: 300: /** 301: * Append the <code>String</code> value of the argument to this 302: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 303: * to <code>String</code>. 304: * 305: * @param inum the <code>int</code> to convert and append 306: * @return this <code>StringBuilder</code> 307: * @see String#valueOf(int) 308: */ 309: // This is native in libgcj, for efficiency. 310: public StringBuilder append(int inum) 311: { 312: super.append(inum); 313: return this; 314: } 315: 316: /** 317: * Append the <code>String</code> value of the argument to this 318: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 319: * to <code>String</code>. 320: * 321: * @param lnum the <code>long</code> to convert and append 322: * @return this <code>StringBuilder</code> 323: * @see String#valueOf(long) 324: */ 325: public StringBuilder append(long lnum) 326: { 327: super.append(lnum); 328: return this; 329: } 330: 331: /** 332: * Append the <code>String</code> value of the argument to this 333: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 334: * to <code>String</code>. 335: * 336: * @param fnum the <code>float</code> to convert and append 337: * @return this <code>StringBuilder</code> 338: * @see String#valueOf(float) 339: */ 340: public StringBuilder append(float fnum) 341: { 342: super.append(fnum); 343: return this; 344: } 345: 346: /** 347: * Append the <code>String</code> value of the argument to this 348: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 349: * to <code>String</code>. 350: * 351: * @param dnum the <code>double</code> to convert and append 352: * @return this <code>StringBuilder</code> 353: * @see String#valueOf(double) 354: */ 355: public StringBuilder append(double dnum) 356: { 357: super.append(dnum); 358: return this; 359: } 360: 361: /** 362: * Append the code point to this <code>StringBuilder</code>. 363: * This is like #append(char), but will append two characters 364: * if a supplementary code point is given. 365: * 366: * @param code the code point to append 367: * @return this <code>StringBuilder</code> 368: * @see Character#toChars(int, char[], int) 369: * @since 1.5 370: */ 371: public StringBuilder appendCodePoint(int code) 372: { 373: super.appendCodePoint(code); 374: return this; 375: } 376: 377: /** 378: * Delete characters from this <code>StringBuilder</code>. 379: * <code>delete(10, 12)</code> will delete 10 and 11, but not 12. It is 380: * harmless for end to be larger than length(). 381: * 382: * @param start the first character to delete 383: * @param end the index after the last character to delete 384: * @return this <code>StringBuilder</code> 385: * @throws StringIndexOutOfBoundsException if start or end are out of bounds 386: */ 387: public StringBuilder delete(int start, int end) 388: { 389: super.delete(start, end); 390: return this; 391: } 392: 393: /** 394: * Delete a character from this <code>StringBuilder</code>. 395: * 396: * @param index the index of the character to delete 397: * @return this <code>StringBuilder</code> 398: * @throws StringIndexOutOfBoundsException if index is out of bounds 399: */ 400: public StringBuilder deleteCharAt(int index) 401: { 402: super.deleteCharAt(index); 403: return this; 404: } 405: 406: /** 407: * Replace characters between index <code>start</code> (inclusive) and 408: * <code>end</code> (exclusive) with <code>str</code>. If <code>end</code> 409: * is larger than the size of this StringBuilder, all characters after 410: * <code>start</code> are replaced. 411: * 412: * @param start the beginning index of characters to delete (inclusive) 413: * @param end the ending index of characters to delete (exclusive) 414: * @param str the new <code>String</code> to insert 415: * @return this <code>StringBuilder</code> 416: * @throws StringIndexOutOfBoundsException if start or end are out of bounds 417: * @throws NullPointerException if str is null 418: */ 419: public StringBuilder replace(int start, int end, String str) 420: { 421: super.replace(start, end, str); 422: return this; 423: } 424: 425: /** 426: * Creates a substring of this StringBuilder, starting at a specified index 427: * and ending at the end of this StringBuilder. 428: * 429: * @param beginIndex index to start substring (base 0) 430: * @return new String which is a substring of this StringBuilder 431: * @throws StringIndexOutOfBoundsException if beginIndex is out of bounds 432: * @see #substring(int, int) 433: */ 434: public String substring(int beginIndex) 435: { 436: return substring(beginIndex, count); 437: } 438: 439: /** 440: * Creates a substring of this StringBuilder, starting at a specified index 441: * and ending at one character before a specified index. This is implemented 442: * the same as <code>substring(beginIndex, endIndex)</code>, to satisfy 443: * the CharSequence interface. 444: * 445: * @param beginIndex index to start at (inclusive, base 0) 446: * @param endIndex index to end at (exclusive) 447: * @return new String which is a substring of this StringBuilder 448: * @throws IndexOutOfBoundsException if beginIndex or endIndex is out of 449: * bounds 450: * @see #substring(int, int) 451: */ 452: public CharSequence subSequence(int beginIndex, int endIndex) 453: { 454: return substring(beginIndex, endIndex); 455: } 456: 457: /** 458: * Creates a substring of this StringBuilder, starting at a specified index 459: * and ending at one character before a specified index. 460: * 461: * @param beginIndex index to start at (inclusive, base 0) 462: * @param endIndex index to end at (exclusive) 463: * @return new String which is a substring of this StringBuilder 464: * @throws StringIndexOutOfBoundsException if beginIndex or endIndex is out 465: * of bounds 466: */ 467: public String substring(int beginIndex, int endIndex) 468: { 469: int len = endIndex - beginIndex; 470: if (beginIndex < 0 || endIndex > count || endIndex < beginIndex) 471: throw new StringIndexOutOfBoundsException(); 472: if (len == 0) 473: return ""; 474: return new String(value, beginIndex, len); 475: } 476: 477: /** 478: * Insert a subarray of the <code>char[]</code> argument into this 479: * <code>StringBuilder</code>. 480: * 481: * @param offset the place to insert in this buffer 482: * @param str the <code>char[]</code> to insert 483: * @param str_offset the index in <code>str</code> to start inserting from 484: * @param len the number of characters to insert 485: * @return this <code>StringBuilder</code> 486: * @throws NullPointerException if <code>str</code> is <code>null</code> 487: * @throws StringIndexOutOfBoundsException if any index is out of bounds 488: */ 489: public StringBuilder insert(int offset, 490: char[] str, int str_offset, int len) 491: { 492: super.insert(offset, str, str_offset, len); 493: return this; 494: } 495: 496: /** 497: * Insert the <code>String</code> value of the argument into this 498: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 499: * to <code>String</code>. 500: * 501: * @param offset the place to insert in this buffer 502: * @param obj the <code>Object</code> to convert and insert 503: * @return this <code>StringBuilder</code> 504: * @exception StringIndexOutOfBoundsException if offset is out of bounds 505: * @see String#valueOf(Object) 506: */ 507: public StringBuilder insert(int offset, Object obj) 508: { 509: super.insert(offset, obj); 510: return this; 511: } 512: 513: /** 514: * Insert the <code>String</code> argument into this 515: * <code>StringBuilder</code>. If str is null, the String "null" is used 516: * instead. 517: * 518: * @param offset the place to insert in this buffer 519: * @param str the <code>String</code> to insert 520: * @return this <code>StringBuilder</code> 521: * @throws StringIndexOutOfBoundsException if offset is out of bounds 522: */ 523: public StringBuilder insert(int offset, String str) 524: { 525: super.insert(offset, str); 526: return this; 527: } 528: 529: /** 530: * Insert the <code>CharSequence</code> argument into this 531: * <code>StringBuilder</code>. If the sequence is null, the String 532: * "null" is used instead. 533: * 534: * @param offset the place to insert in this buffer 535: * @param sequence the <code>CharSequence</code> to insert 536: * @return this <code>StringBuilder</code> 537: * @throws IndexOutOfBoundsException if offset is out of bounds 538: */ 539: public StringBuilder insert(int offset, CharSequence sequence) 540: { 541: super.insert(offset, sequence); 542: return this; 543: } 544: 545: /** 546: * Insert a subsequence of the <code>CharSequence</code> argument into this 547: * <code>StringBuilder</code>. If the sequence is null, the String 548: * "null" is used instead. 549: * 550: * @param offset the place to insert in this buffer 551: * @param sequence the <code>CharSequence</code> to insert 552: * @param start the starting index of the subsequence 553: * @param end one past the ending index of the subsequence 554: * @return this <code>StringBuilder</code> 555: * @throws IndexOutOfBoundsException if offset, start, 556: * or end are out of bounds 557: */ 558: public StringBuilder insert(int offset, CharSequence sequence, 559: int start, int end) 560: { 561: super.insert(offset, sequence, start, end); 562: return this; 563: } 564: 565: /** 566: * Insert the <code>char[]</code> argument into this 567: * <code>StringBuilder</code>. 568: * 569: * @param offset the place to insert in this buffer 570: * @param data the <code>char[]</code> to insert 571: * @return this <code>StringBuilder</code> 572: * @throws NullPointerException if <code>data</code> is <code>null</code> 573: * @throws StringIndexOutOfBoundsException if offset is out of bounds 574: * @see #insert(int, char[], int, int) 575: */ 576: public StringBuilder insert(int offset, char[] data) 577: { 578: super.insert(offset, data); 579: return this; 580: } 581: 582: /** 583: * Insert the <code>String</code> value of the argument into this 584: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 585: * to <code>String</code>. 586: * 587: * @param offset the place to insert in this buffer 588: * @param bool the <code>boolean</code> to convert and insert 589: * @return this <code>StringBuilder</code> 590: * @throws StringIndexOutOfBoundsException if offset is out of bounds 591: * @see String#valueOf(boolean) 592: */ 593: public StringBuilder insert(int offset, boolean bool) 594: { 595: super.insert(offset, bool); 596: return this; 597: } 598: 599: /** 600: * Insert the <code>char</code> argument into this <code>StringBuilder</code>. 601: * 602: * @param offset the place to insert in this buffer 603: * @param ch the <code>char</code> to insert 604: * @return this <code>StringBuilder</code> 605: * @throws StringIndexOutOfBoundsException if offset is out of bounds 606: */ 607: public StringBuilder insert(int offset, char ch) 608: { 609: super.insert(offset, ch); 610: return this; 611: } 612: 613: /** 614: * Insert the <code>String</code> value of the argument into this 615: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 616: * to <code>String</code>. 617: * 618: * @param offset the place to insert in this buffer 619: * @param inum the <code>int</code> to convert and insert 620: * @return this <code>StringBuilder</code> 621: * @throws StringIndexOutOfBoundsException if offset is out of bounds 622: * @see String#valueOf(int) 623: */ 624: public StringBuilder insert(int offset, int inum) 625: { 626: super.insert(offset, inum); 627: return this; 628: } 629: 630: /** 631: * Insert the <code>String</code> value of the argument into this 632: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 633: * to <code>String</code>. 634: * 635: * @param offset the place to insert in this buffer 636: * @param lnum the <code>long</code> to convert and insert 637: * @return this <code>StringBuilder</code> 638: * @throws StringIndexOutOfBoundsException if offset is out of bounds 639: * @see String#valueOf(long) 640: */ 641: public StringBuilder insert(int offset, long lnum) 642: { 643: super.insert(offset, lnum); 644: return this; 645: } 646: 647: /** 648: * Insert the <code>String</code> value of the argument into this 649: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 650: * to <code>String</code>. 651: * 652: * @param offset the place to insert in this buffer 653: * @param fnum the <code>float</code> to convert and insert 654: * @return this <code>StringBuilder</code> 655: * @throws StringIndexOutOfBoundsException if offset is out of bounds 656: * @see String#valueOf(float) 657: */ 658: public StringBuilder insert(int offset, float fnum) 659: { 660: super.insert(offset, fnum); 661: return this; 662: } 663: 664: /** 665: * Insert the <code>String</code> value of the argument into this 666: * <code>StringBuilder</code>. Uses <code>String.valueOf()</code> to convert 667: * to <code>String</code>. 668: * 669: * @param offset the place to insert in this buffer 670: * @param dnum the <code>double</code> to convert and insert 671: * @return this <code>StringBuilder</code> 672: * @throws StringIndexOutOfBoundsException if offset is out of bounds 673: * @see String#valueOf(double) 674: */ 675: public StringBuilder insert(int offset, double dnum) 676: { 677: super.insert(offset, dnum); 678: return this; 679: } 680: 681: /** 682: * Reverse the characters in this StringBuilder. The same sequence of 683: * characters exists, but in the reverse index ordering. 684: * 685: * @return this <code>StringBuilder</code> 686: */ 687: public StringBuilder reverse() 688: { 689: super.reverse(); 690: return this; 691: } 692: 693: /** 694: * Convert this <code>StringBuilder</code> to a <code>String</code>. The 695: * String is composed of the characters currently in this StringBuilder. Note 696: * that the result is a copy, and that future modifications to this buffer 697: * do not affect the String. 698: * 699: * @return the characters in this StringBuilder 700: */ 701: public String toString() 702: { 703: return new String(this); 704: } 705: 706: }