1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * Copyright (c) 2003, 2018, 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 import dalvik.annotation.optimization.NeverInline; 30 import jdk.internal.HotSpotIntrinsicCandidate; 31 32 /** 33 * A mutable sequence of characters. This class provides an API compatible 34 * with {@code StringBuffer}, but with no guarantee of synchronization. 35 * This class is designed for use as a drop-in replacement for 36 * {@code StringBuffer} in places where the string buffer was being 37 * used by a single thread (as is generally the case). Where possible, 38 * it is recommended that this class be used in preference to 39 * {@code StringBuffer} as it will be faster under most implementations. 40 * 41 * <p>The principal operations on a {@code StringBuilder} are the 42 * {@code append} and {@code insert} methods, which are 43 * overloaded so as to accept data of any type. Each effectively 44 * converts a given datum to a string and then appends or inserts the 45 * characters of that string to the string builder. The 46 * {@code append} method always adds these characters at the end 47 * of the builder; the {@code insert} method adds the characters at 48 * a specified point. 49 * <p> 50 * For example, if {@code z} refers to a string builder object 51 * whose current contents are "{@code start}", then 52 * the method call {@code z.append("le")} would cause the string 53 * builder to contain "{@code startle}", whereas 54 * {@code z.insert(4, "le")} would alter the string builder to 55 * contain "{@code starlet}". 56 * <p> 57 * In general, if sb refers to an instance of a {@code StringBuilder}, 58 * then {@code sb.append(x)} has the same effect as 59 * {@code sb.insert(sb.length(), x)}. 60 * <p> 61 * Every string builder has a capacity. As long as the length of the 62 * character sequence contained in the string builder does not exceed 63 * the capacity, it is not necessary to allocate a new internal 64 * buffer. If the internal buffer overflows, it is automatically made larger. 65 * 66 * <p>Instances of {@code StringBuilder} are not safe for 67 * use by multiple threads. If such synchronization is required then it is 68 * recommended that {@link java.lang.StringBuffer} be used. 69 * 70 * <p>Unless otherwise noted, passing a {@code null} argument to a constructor 71 * or method in this class will cause a {@link NullPointerException} to be 72 * thrown. 73 * 74 * @apiNote 75 * {@code StringBuilder} implements {@code Comparable} but does not override 76 * {@link Object#equals equals}. Thus, the natural ordering of {@code StringBuilder} 77 * is inconsistent with equals. Care should be exercised if {@code StringBuilder} 78 * objects are used as keys in a {@code SortedMap} or elements in a {@code SortedSet}. 79 * See {@link Comparable}, {@link java.util.SortedMap SortedMap}, or 80 * {@link java.util.SortedSet SortedSet} for more information. 81 * 82 * @author Michael McCloskey 83 * @see java.lang.StringBuffer 84 * @see java.lang.String 85 * @since 1.5 86 */ 87 public final class StringBuilder 88 extends AbstractStringBuilder 89 implements java.io.Serializable, Comparable<StringBuilder>, CharSequence 90 { 91 92 /** use serialVersionUID for interoperability */ 93 static final long serialVersionUID = 4383685877147921099L; 94 95 // Android-changed: Add @NeverInline for InstructionSimplifier optimization. See b/19575890. 96 /** 97 * Constructs a string builder with no characters in it and an 98 * initial capacity of 16 characters. 99 */ 100 @NeverInline 101 @HotSpotIntrinsicCandidate StringBuilder()102 public StringBuilder() { 103 super(16); 104 } 105 106 // Android-changed: Add @NeverInline for InstructionSimplifier optimization. See b/19575890. 107 /** 108 * Constructs a string builder with no characters in it and an 109 * initial capacity specified by the {@code capacity} argument. 110 * 111 * @param capacity the initial capacity. 112 * @throws NegativeArraySizeException if the {@code capacity} 113 * argument is less than {@code 0}. 114 */ 115 @NeverInline 116 @HotSpotIntrinsicCandidate StringBuilder(int capacity)117 public StringBuilder(int capacity) { 118 super(capacity); 119 } 120 121 // Android-changed: Add @NeverInline for InstructionSimplifier optimization. See b/19575890. 122 /** 123 * Constructs a string builder initialized to the contents of the 124 * specified string. The initial capacity of the string builder is 125 * {@code 16} plus the length of the string argument. 126 * 127 * @param str the initial contents of the buffer. 128 */ 129 @NeverInline 130 @HotSpotIntrinsicCandidate StringBuilder(String str)131 public StringBuilder(String str) { 132 super(str.length() + 16); 133 append(str); 134 } 135 136 // Android-changed: Add @NeverInline for InstructionSimplifier optimization. See b/19575890. 137 /** 138 * Constructs a string builder that contains the same characters 139 * as the specified {@code CharSequence}. The initial capacity of 140 * the string builder is {@code 16} plus the length of the 141 * {@code CharSequence} argument. 142 * 143 * @param seq the sequence to copy. 144 */ 145 @NeverInline StringBuilder(CharSequence seq)146 public StringBuilder(CharSequence seq) { 147 this(seq.length() + 16); 148 append(seq); 149 } 150 151 /** 152 * Compares two {@code StringBuilder} instances lexicographically. This method 153 * follows the same rules for lexicographical comparison as defined in the 154 * {@linkplain java.lang.CharSequence#compare(java.lang.CharSequence, 155 * java.lang.CharSequence) CharSequence.compare(this, another)} method. 156 * 157 * <p> 158 * For finer-grained, locale-sensitive String comparison, refer to 159 * {@link java.text.Collator}. 160 * 161 * @param another the {@code StringBuilder} to be compared with 162 * 163 * @return the value {@code 0} if this {@code StringBuilder} contains the same 164 * character sequence as that of the argument {@code StringBuilder}; a negative integer 165 * if this {@code StringBuilder} is lexicographically less than the 166 * {@code StringBuilder} argument; or a positive integer if this {@code StringBuilder} 167 * is lexicographically greater than the {@code StringBuilder} argument. 168 * 169 * @since 11 170 */ 171 @Override compareTo(StringBuilder another)172 public int compareTo(StringBuilder another) { 173 return super.compareTo(another); 174 } 175 176 @Override 177 @NeverInline append(Object obj)178 public StringBuilder append(Object obj) { 179 return append(String.valueOf(obj)); 180 } 181 182 @Override 183 @HotSpotIntrinsicCandidate 184 @NeverInline append(String str)185 public StringBuilder append(String str) { 186 super.append(str); 187 return this; 188 } 189 190 /** 191 * Appends the specified {@code StringBuffer} to this sequence. 192 * <p> 193 * The characters of the {@code StringBuffer} argument are appended, 194 * in order, to this sequence, increasing the 195 * length of this sequence by the length of the argument. 196 * If {@code sb} is {@code null}, then the four characters 197 * {@code "null"} are appended to this sequence. 198 * <p> 199 * Let <i>n</i> be the length of this character sequence just prior to 200 * execution of the {@code append} method. Then the character at index 201 * <i>k</i> in the new character sequence is equal to the character at 202 * index <i>k</i> in the old character sequence, if <i>k</i> is less than 203 * <i>n</i>; otherwise, it is equal to the character at index <i>k-n</i> 204 * in the argument {@code sb}. 205 * 206 * @param sb the {@code StringBuffer} to append. 207 * @return a reference to this object. 208 */ append(StringBuffer sb)209 public StringBuilder append(StringBuffer sb) { 210 super.append(sb); 211 return this; 212 } 213 214 @Override 215 @NeverInline append(CharSequence s)216 public StringBuilder append(CharSequence s) { 217 super.append(s); 218 return this; 219 } 220 221 /** 222 * @throws IndexOutOfBoundsException {@inheritDoc} 223 */ 224 @Override append(CharSequence s, int start, int end)225 public StringBuilder append(CharSequence s, int start, int end) { 226 super.append(s, start, end); 227 return this; 228 } 229 230 @Override 231 @NeverInline append(char[] str)232 public StringBuilder append(char[] str) { 233 super.append(str); 234 return this; 235 } 236 237 /** 238 * @throws IndexOutOfBoundsException {@inheritDoc} 239 */ 240 @Override append(char[] str, int offset, int len)241 public StringBuilder append(char[] str, int offset, int len) { 242 super.append(str, offset, len); 243 return this; 244 } 245 246 @Override 247 @NeverInline append(boolean b)248 public StringBuilder append(boolean b) { 249 super.append(b); 250 return this; 251 } 252 253 @Override 254 @HotSpotIntrinsicCandidate 255 @NeverInline append(char c)256 public StringBuilder append(char c) { 257 super.append(c); 258 return this; 259 } 260 261 @Override 262 @HotSpotIntrinsicCandidate 263 @NeverInline append(int i)264 public StringBuilder append(int i) { 265 super.append(i); 266 return this; 267 } 268 269 @Override 270 @NeverInline append(long lng)271 public StringBuilder append(long lng) { 272 super.append(lng); 273 return this; 274 } 275 276 @Override 277 @NeverInline append(float f)278 public StringBuilder append(float f) { 279 super.append(f); 280 return this; 281 } 282 283 @Override 284 @NeverInline append(double d)285 public StringBuilder append(double d) { 286 super.append(d); 287 return this; 288 } 289 290 /** 291 * @since 1.5 292 */ 293 @Override appendCodePoint(int codePoint)294 public StringBuilder appendCodePoint(int codePoint) { 295 super.appendCodePoint(codePoint); 296 return this; 297 } 298 299 /** 300 * @throws StringIndexOutOfBoundsException {@inheritDoc} 301 */ 302 @Override delete(int start, int end)303 public StringBuilder delete(int start, int end) { 304 super.delete(start, end); 305 return this; 306 } 307 308 /** 309 * @throws StringIndexOutOfBoundsException {@inheritDoc} 310 */ 311 @Override deleteCharAt(int index)312 public StringBuilder deleteCharAt(int index) { 313 super.deleteCharAt(index); 314 return this; 315 } 316 317 /** 318 * @throws StringIndexOutOfBoundsException {@inheritDoc} 319 */ 320 @Override replace(int start, int end, String str)321 public StringBuilder replace(int start, int end, String str) { 322 super.replace(start, end, str); 323 return this; 324 } 325 326 /** 327 * @throws StringIndexOutOfBoundsException {@inheritDoc} 328 */ 329 @Override insert(int index, char[] str, int offset, int len)330 public StringBuilder insert(int index, char[] str, int offset, 331 int len) 332 { 333 super.insert(index, str, offset, len); 334 return this; 335 } 336 337 /** 338 * @throws StringIndexOutOfBoundsException {@inheritDoc} 339 */ 340 @Override insert(int offset, Object obj)341 public StringBuilder insert(int offset, Object obj) { 342 super.insert(offset, obj); 343 return this; 344 } 345 346 /** 347 * @throws StringIndexOutOfBoundsException {@inheritDoc} 348 */ 349 @Override insert(int offset, String str)350 public StringBuilder insert(int offset, String str) { 351 super.insert(offset, str); 352 return this; 353 } 354 355 /** 356 * @throws StringIndexOutOfBoundsException {@inheritDoc} 357 */ 358 @Override insert(int offset, char[] str)359 public StringBuilder insert(int offset, char[] str) { 360 super.insert(offset, str); 361 return this; 362 } 363 364 /** 365 * @throws IndexOutOfBoundsException {@inheritDoc} 366 */ 367 @Override insert(int dstOffset, CharSequence s)368 public StringBuilder insert(int dstOffset, CharSequence s) { 369 super.insert(dstOffset, s); 370 return this; 371 } 372 373 /** 374 * @throws IndexOutOfBoundsException {@inheritDoc} 375 */ 376 @Override insert(int dstOffset, CharSequence s, int start, int end)377 public StringBuilder insert(int dstOffset, CharSequence s, 378 int start, int end) 379 { 380 super.insert(dstOffset, s, start, end); 381 return this; 382 } 383 384 /** 385 * @throws StringIndexOutOfBoundsException {@inheritDoc} 386 */ 387 @Override insert(int offset, boolean b)388 public StringBuilder insert(int offset, boolean b) { 389 super.insert(offset, b); 390 return this; 391 } 392 393 /** 394 * @throws IndexOutOfBoundsException {@inheritDoc} 395 */ 396 @Override insert(int offset, char c)397 public StringBuilder insert(int offset, char c) { 398 super.insert(offset, c); 399 return this; 400 } 401 402 /** 403 * @throws StringIndexOutOfBoundsException {@inheritDoc} 404 */ 405 @Override insert(int offset, int i)406 public StringBuilder insert(int offset, int i) { 407 super.insert(offset, i); 408 return this; 409 } 410 411 /** 412 * @throws StringIndexOutOfBoundsException {@inheritDoc} 413 */ 414 @Override insert(int offset, long l)415 public StringBuilder insert(int offset, long l) { 416 super.insert(offset, l); 417 return this; 418 } 419 420 /** 421 * @throws StringIndexOutOfBoundsException {@inheritDoc} 422 */ 423 @Override insert(int offset, float f)424 public StringBuilder insert(int offset, float f) { 425 super.insert(offset, f); 426 return this; 427 } 428 429 /** 430 * @throws StringIndexOutOfBoundsException {@inheritDoc} 431 */ 432 @Override insert(int offset, double d)433 public StringBuilder insert(int offset, double d) { 434 super.insert(offset, d); 435 return this; 436 } 437 438 @Override indexOf(String str)439 public int indexOf(String str) { 440 return super.indexOf(str); 441 } 442 443 @Override indexOf(String str, int fromIndex)444 public int indexOf(String str, int fromIndex) { 445 return super.indexOf(str, fromIndex); 446 } 447 448 @Override lastIndexOf(String str)449 public int lastIndexOf(String str) { 450 return super.lastIndexOf(str); 451 } 452 453 @Override lastIndexOf(String str, int fromIndex)454 public int lastIndexOf(String str, int fromIndex) { 455 return super.lastIndexOf(str, fromIndex); 456 } 457 458 @Override reverse()459 public StringBuilder reverse() { 460 super.reverse(); 461 return this; 462 } 463 464 @Override 465 @HotSpotIntrinsicCandidate 466 @NeverInline toString()467 public String toString() { 468 // BEGIN Android-added: Return a constant "" for an empty buffer to keep historic behavior. 469 if (count == 0) { 470 return ""; 471 } 472 // END Android-added: Return a constant "" for an empty buffer to keep historic behavior. 473 // Create a copy, don't share the array 474 return isLatin1() ? StringLatin1.newString(value, 0, count) 475 : StringUTF16.newString(value, 0, count); 476 } 477 478 /** 479 * Save the state of the {@code StringBuilder} instance to a stream 480 * (that is, serialize it). 481 * 482 * @serialData the number of characters currently stored in the string 483 * builder ({@code int}), followed by the characters in the 484 * string builder ({@code char[]}). The length of the 485 * {@code char} array may be greater than the number of 486 * characters currently stored in the string builder, in which 487 * case extra characters are ignored. 488 */ writeObject(java.io.ObjectOutputStream s)489 private void writeObject(java.io.ObjectOutputStream s) 490 throws java.io.IOException { 491 s.defaultWriteObject(); 492 s.writeInt(count); 493 char[] val = new char[capacity()]; 494 if (isLatin1()) { 495 StringLatin1.getChars(value, 0, count, val, 0); 496 } else { 497 StringUTF16.getChars(value, 0, count, val, 0); 498 } 499 s.writeObject(val); 500 } 501 502 /** 503 * readObject is called to restore the state of the StringBuffer from 504 * a stream. 505 */ readObject(java.io.ObjectInputStream s)506 private void readObject(java.io.ObjectInputStream s) 507 throws java.io.IOException, ClassNotFoundException { 508 s.defaultReadObject(); 509 count = s.readInt(); 510 char[] val = (char[]) s.readObject(); 511 initBytes(val, 0, val.length); 512 } 513 514 } 515