1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. Oracle designates this 9 * particular file as subject to the "Classpath" exception as provided 10 * by Oracle in the LICENSE file that accompanied this code. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23 * or visit www.oracle.com if you need additional information or have any 24 * questions. 25 */ 26 27 package java.lang; 28 29 30 /** 31 * A mutable sequence of characters. This class provides an API compatible 32 * with <code>StringBuffer</code>, but with no guarantee of synchronization. 33 * This class is designed for use as a drop-in replacement for 34 * <code>StringBuffer</code> in places where the string buffer was being 35 * used by a single thread (as is generally the case). Where possible, 36 * it is recommended that this class be used in preference to 37 * <code>StringBuffer</code> as it will be faster under most implementations. 38 * 39 * <p>The principal operations on a <code>StringBuilder</code> are the 40 * <code>append</code> and <code>insert</code> methods, which are 41 * overloaded so as to accept data of any type. Each effectively 42 * converts a given datum to a string and then appends or inserts the 43 * characters of that string to the string builder. The 44 * <code>append</code> method always adds these characters at the end 45 * of the builder; the <code>insert</code> method adds the characters at 46 * a specified point. 47 * <p> 48 * For example, if <code>z</code> refers to a string builder object 49 * whose current contents are "<code>start</code>", then 50 * the method call <code>z.append("le")</code> would cause the string 51 * builder to contain "<code>startle</code>", whereas 52 * <code>z.insert(4, "le")</code> would alter the string builder to 53 * contain "<code>starlet</code>". 54 * <p> 55 * In general, if sb refers to an instance of a <code>StringBuilder</code>, 56 * then <code>sb.append(x)</code> has the same effect as 57 * <code>sb.insert(sb.length(), x)</code>. 58 * 59 * Every string builder has a capacity. As long as the length of the 60 * character sequence contained in the string builder does not exceed 61 * the capacity, it is not necessary to allocate a new internal 62 * buffer. If the internal buffer overflows, it is automatically made larger. 63 * 64 * <p>Instances of <code>StringBuilder</code> are not safe for 65 * use by multiple threads. If such synchronization is required then it is 66 * recommended that {@link java.lang.StringBuffer} be used. 67 * 68 * @author Michael McCloskey 69 * @see java.lang.StringBuffer 70 * @see java.lang.String 71 * @since 1.5 72 */ 73 public final class StringBuilder 74 extends AbstractStringBuilder 75 implements java.io.Serializable, Appendable, CharSequence 76 { 77 78 /** use serialVersionUID for interoperability */ 79 static final long serialVersionUID = 4383685877147921099L; 80 81 /** 82 * Constructs a string builder with no characters in it and an 83 * initial capacity of 16 characters. 84 */ StringBuilder()85 public StringBuilder() { 86 super(16); 87 } 88 89 /** 90 * Constructs a string builder with no characters in it and an 91 * initial capacity specified by the <code>capacity</code> argument. 92 * 93 * @param capacity the initial capacity. 94 * @throws NegativeArraySizeException if the <code>capacity</code> 95 * argument is less than <code>0</code>. 96 */ StringBuilder(int capacity)97 public StringBuilder(int capacity) { 98 super(capacity); 99 } 100 101 /** 102 * Constructs a string builder initialized to the contents of the 103 * specified string. The initial capacity of the string builder is 104 * <code>16</code> plus the length of the string argument. 105 * 106 * @param str the initial contents of the buffer. 107 * @throws NullPointerException if <code>str</code> is <code>null</code> 108 */ StringBuilder(String str)109 public StringBuilder(String str) { 110 super(str.length() + 16); 111 append(str); 112 } 113 114 /** 115 * Constructs a string builder that contains the same characters 116 * as the specified <code>CharSequence</code>. The initial capacity of 117 * the string builder is <code>16</code> plus the length of the 118 * <code>CharSequence</code> argument. 119 * 120 * @param seq the sequence to copy. 121 * @throws NullPointerException if <code>seq</code> is <code>null</code> 122 */ StringBuilder(CharSequence seq)123 public StringBuilder(CharSequence seq) { 124 this(seq.length() + 16); 125 append(seq); 126 } 127 append(Object obj)128 public StringBuilder append(Object obj) { 129 return append(String.valueOf(obj)); 130 } 131 append(String str)132 public StringBuilder append(String str) { 133 super.append(str); 134 return this; 135 } 136 137 // Appends the specified string builder to this sequence. append(StringBuilder sb)138 private StringBuilder append(StringBuilder sb) { 139 if (sb == null) 140 return append("null"); 141 int len = sb.length(); 142 int newcount = count + len; 143 if (newcount > value.length) 144 expandCapacity(newcount); 145 sb.getChars(0, len, value, count); 146 count = newcount; 147 return this; 148 } 149 150 /** 151 * Appends the specified <tt>StringBuffer</tt> to this sequence. 152 * <p> 153 * The characters of the <tt>StringBuffer</tt> argument are appended, 154 * in order, to this sequence, increasing the 155 * length of this sequence by the length of the argument. 156 * If <tt>sb</tt> is <tt>null</tt>, then the four characters 157 * <tt>"null"</tt> are appended to this sequence. 158 * <p> 159 * Let <i>n</i> be the length of this character sequence just prior to 160 * execution of the <tt>append</tt> method. Then the character at index 161 * <i>k</i> in the new character sequence is equal to the character at 162 * index <i>k</i> in the old character sequence, if <i>k</i> is less than 163 * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i> 164 * in the argument <code>sb</code>. 165 * 166 * @param sb the <tt>StringBuffer</tt> to append. 167 * @return a reference to this object. 168 */ append(StringBuffer sb)169 public StringBuilder append(StringBuffer sb) { 170 super.append(sb); 171 return this; 172 } 173 174 /** 175 */ append(CharSequence s)176 public StringBuilder append(CharSequence s) { 177 if (s == null) 178 s = "null"; 179 if (s instanceof String) 180 return this.append((String)s); 181 if (s instanceof StringBuffer) 182 return this.append((StringBuffer)s); 183 if (s instanceof StringBuilder) 184 return this.append((StringBuilder)s); 185 return this.append(s, 0, s.length()); 186 } 187 188 /** 189 * @throws IndexOutOfBoundsException {@inheritDoc} 190 */ append(CharSequence s, int start, int end)191 public StringBuilder append(CharSequence s, int start, int end) { 192 super.append(s, start, end); 193 return this; 194 } 195 append(char[] str)196 public StringBuilder append(char[] str) { 197 super.append(str); 198 return this; 199 } 200 201 /** 202 * @throws IndexOutOfBoundsException {@inheritDoc} 203 */ append(char[] str, int offset, int len)204 public StringBuilder append(char[] str, int offset, int len) { 205 super.append(str, offset, len); 206 return this; 207 } 208 append(boolean b)209 public StringBuilder append(boolean b) { 210 super.append(b); 211 return this; 212 } 213 append(char c)214 public StringBuilder append(char c) { 215 super.append(c); 216 return this; 217 } 218 append(int i)219 public StringBuilder append(int i) { 220 super.append(i); 221 return this; 222 } 223 append(long lng)224 public StringBuilder append(long lng) { 225 super.append(lng); 226 return this; 227 } 228 append(float f)229 public StringBuilder append(float f) { 230 super.append(f); 231 return this; 232 } 233 append(double d)234 public StringBuilder append(double d) { 235 super.append(d); 236 return this; 237 } 238 239 /** 240 * @since 1.5 241 */ appendCodePoint(int codePoint)242 public StringBuilder appendCodePoint(int codePoint) { 243 super.appendCodePoint(codePoint); 244 return this; 245 } 246 247 /** 248 * @throws StringIndexOutOfBoundsException {@inheritDoc} 249 */ delete(int start, int end)250 public StringBuilder delete(int start, int end) { 251 super.delete(start, end); 252 return this; 253 } 254 255 /** 256 * @throws StringIndexOutOfBoundsException {@inheritDoc} 257 */ deleteCharAt(int index)258 public StringBuilder deleteCharAt(int index) { 259 super.deleteCharAt(index); 260 return this; 261 } 262 263 /** 264 * @throws StringIndexOutOfBoundsException {@inheritDoc} 265 */ replace(int start, int end, String str)266 public StringBuilder replace(int start, int end, String str) { 267 super.replace(start, end, str); 268 return this; 269 } 270 271 /** 272 * @throws StringIndexOutOfBoundsException {@inheritDoc} 273 */ insert(int index, char[] str, int offset, int len)274 public StringBuilder insert(int index, char[] str, int offset, 275 int len) 276 { 277 super.insert(index, str, offset, len); 278 return this; 279 } 280 281 /** 282 * @throws StringIndexOutOfBoundsException {@inheritDoc} 283 */ insert(int offset, Object obj)284 public StringBuilder insert(int offset, Object obj) { 285 return insert(offset, String.valueOf(obj)); 286 } 287 288 /** 289 * @throws StringIndexOutOfBoundsException {@inheritDoc} 290 */ insert(int offset, String str)291 public StringBuilder insert(int offset, String str) { 292 super.insert(offset, str); 293 return this; 294 } 295 296 /** 297 * @throws StringIndexOutOfBoundsException {@inheritDoc} 298 */ insert(int offset, char[] str)299 public StringBuilder insert(int offset, char[] str) { 300 super.insert(offset, str); 301 return this; 302 } 303 304 /** 305 * @throws IndexOutOfBoundsException {@inheritDoc} 306 */ insert(int dstOffset, CharSequence s)307 public StringBuilder insert(int dstOffset, CharSequence s) { 308 if (s == null) 309 s = "null"; 310 if (s instanceof String) 311 return this.insert(dstOffset, (String)s); 312 return this.insert(dstOffset, s, 0, s.length()); 313 } 314 315 /** 316 * @throws IndexOutOfBoundsException {@inheritDoc} 317 */ insert(int dstOffset, CharSequence s, int start, int end)318 public StringBuilder insert(int dstOffset, CharSequence s, 319 int start, int end) 320 { 321 super.insert(dstOffset, s, start, end); 322 return this; 323 } 324 325 /** 326 * @throws StringIndexOutOfBoundsException {@inheritDoc} 327 */ insert(int offset, boolean b)328 public StringBuilder insert(int offset, boolean b) { 329 super.insert(offset, b); 330 return this; 331 } 332 333 /** 334 * @throws IndexOutOfBoundsException {@inheritDoc} 335 */ insert(int offset, char c)336 public StringBuilder insert(int offset, char c) { 337 super.insert(offset, c); 338 return this; 339 } 340 341 /** 342 * @throws StringIndexOutOfBoundsException {@inheritDoc} 343 */ insert(int offset, int i)344 public StringBuilder insert(int offset, int i) { 345 return insert(offset, String.valueOf(i)); 346 } 347 348 /** 349 * @throws StringIndexOutOfBoundsException {@inheritDoc} 350 */ insert(int offset, long l)351 public StringBuilder insert(int offset, long l) { 352 return insert(offset, String.valueOf(l)); 353 } 354 355 /** 356 * @throws StringIndexOutOfBoundsException {@inheritDoc} 357 */ insert(int offset, float f)358 public StringBuilder insert(int offset, float f) { 359 return insert(offset, String.valueOf(f)); 360 } 361 362 /** 363 * @throws StringIndexOutOfBoundsException {@inheritDoc} 364 */ insert(int offset, double d)365 public StringBuilder insert(int offset, double d) { 366 return insert(offset, String.valueOf(d)); 367 } 368 369 /** 370 * @throws NullPointerException {@inheritDoc} 371 */ indexOf(String str)372 public int indexOf(String str) { 373 return indexOf(str, 0); 374 } 375 376 /** 377 * @throws NullPointerException {@inheritDoc} 378 */ indexOf(String str, int fromIndex)379 public int indexOf(String str, int fromIndex) { 380 return String.indexOf(value, 0, count, 381 str.toCharArray(), 0, str.length(), fromIndex); 382 } 383 384 /** 385 * @throws NullPointerException {@inheritDoc} 386 */ lastIndexOf(String str)387 public int lastIndexOf(String str) { 388 return lastIndexOf(str, count); 389 } 390 391 /** 392 * @throws NullPointerException {@inheritDoc} 393 */ lastIndexOf(String str, int fromIndex)394 public int lastIndexOf(String str, int fromIndex) { 395 return String.lastIndexOf(value, 0, count, 396 str.toCharArray(), 0, str.length(), fromIndex); 397 } 398 reverse()399 public StringBuilder reverse() { 400 super.reverse(); 401 return this; 402 } 403 toString()404 public String toString() { 405 if (count == 0) { 406 return ""; 407 } 408 return StringFactory.newStringFromChars(0, count, value); 409 } 410 411 /** 412 * Save the state of the <tt>StringBuilder</tt> instance to a stream 413 * (that is, serialize it). 414 * 415 * @serialData the number of characters currently stored in the string 416 * builder (<tt>int</tt>), followed by the characters in the 417 * string builder (<tt>char[]</tt>). The length of the 418 * <tt>char</tt> array may be greater than the number of 419 * characters currently stored in the string builder, in which 420 * case extra characters are ignored. 421 */ writeObject(java.io.ObjectOutputStream s)422 private void writeObject(java.io.ObjectOutputStream s) 423 throws java.io.IOException { 424 s.defaultWriteObject(); 425 s.writeInt(count); 426 s.writeObject(value); 427 } 428 429 /** 430 * readObject is called to restore the state of the StringBuffer from 431 * a stream. 432 */ readObject(java.io.ObjectInputStream s)433 private void readObject(java.io.ObjectInputStream s) 434 throws java.io.IOException, ClassNotFoundException { 435 s.defaultReadObject(); 436 count = s.readInt(); 437 value = (char[]) s.readObject(); 438 } 439 440 } 441