1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.lang; 19 20 import java.io.Serializable; 21 import java.io.UnsupportedEncodingException; 22 import java.nio.ByteBuffer; 23 import java.nio.CharBuffer; 24 import java.nio.charset.Charset; 25 import java.nio.charset.Charsets; 26 import java.util.Arrays; 27 import java.util.Comparator; 28 import java.util.Formatter; 29 import java.util.Locale; 30 import java.util.regex.Pattern; 31 import libcore.util.EmptyArray; 32 33 /** 34 * An immutable sequence of UTF-16 {@code char}s. 35 * See {@link Character} for details about the relationship between {@code char} and 36 * Unicode code points. 37 * 38 * <a name="backing_array"><h3>Backing Arrays</h3></a> 39 * This class is implemented using a {@code char[]}. The length of the array may exceed 40 * the length of the string. For example, the string "Hello" may be backed by 41 * the array {@code ['H', 'e', 'l', 'l', 'o', 'W'. 'o', 'r', 'l', 'd']} with 42 * offset 0 and length 5. 43 * 44 * <p>Multiple strings can share the same {@code char[]} because strings are immutable. 45 * The {@link #substring} method <strong>always</strong> returns a string that 46 * shares the backing array of its source string. Generally this is an 47 * optimization: fewer {@code char[]}s need to be allocated, and less copying 48 * is necessary. But this can also lead to unwanted heap retention. Taking a 49 * short substring of long string means that the long shared {@code char[]} won't be 50 * garbage until both strings are garbage. This typically happens when parsing 51 * small substrings out of a large input. To avoid this where necessary, call 52 * {@code new String(longString.subString(...))}. The string copy constructor 53 * always ensures that the backing array is no larger than necessary. 54 * 55 * @see StringBuffer 56 * @see StringBuilder 57 * @see Charset 58 * @since 1.0 59 */ 60 public final class String implements Serializable, Comparable<String>, CharSequence { 61 62 private static final long serialVersionUID = -6849794470754667710L; 63 64 private static final char REPLACEMENT_CHAR = (char) 0xfffd; 65 66 private static final class CaseInsensitiveComparator implements 67 Comparator<String>, Serializable { 68 private static final long serialVersionUID = 8575799808933029326L; 69 70 /** 71 * See {@link java.lang.String#compareToIgnoreCase}. 72 * 73 * @exception ClassCastException 74 * if objects are not the correct type 75 */ compare(String o1, String o2)76 public int compare(String o1, String o2) { 77 return o1.compareToIgnoreCase(o2); 78 } 79 } 80 81 /** 82 * Compares strings using {@link #compareToIgnoreCase}. 83 * This is not suitable for case-insensitive string comparison for all locales. 84 * Use a {@link java.text.Collator} instead. 85 */ 86 public static final Comparator<String> CASE_INSENSITIVE_ORDER = new CaseInsensitiveComparator(); 87 88 private static final char[] ASCII; 89 static { 90 ASCII = new char[128]; 91 for (int i = 0; i < ASCII.length; ++i) { 92 ASCII[i] = (char) i; 93 } 94 } 95 96 private final char[] value; 97 98 private final int offset; 99 100 private final int count; 101 102 private int hashCode; 103 104 /** 105 * Creates an empty string. 106 */ String()107 public String() { 108 value = EmptyArray.CHAR; 109 offset = 0; 110 count = 0; 111 } 112 113 /** 114 * Converts the byte array to a string using the system's 115 * {@link java.nio.charset.Charset#defaultCharset default charset}. 116 */ 117 @FindBugsSuppressWarnings("DM_DEFAULT_ENCODING") String(byte[] data)118 public String(byte[] data) { 119 this(data, 0, data.length); 120 } 121 122 /** 123 * Converts the byte array to a string, setting the high byte of every 124 * {@code char} to the specified value. 125 * 126 * @param data 127 * the byte array to convert to a string. 128 * @param high 129 * the high byte to use. 130 * @throws NullPointerException 131 * if {@code data == null}. 132 * @deprecated Use {@link #String(byte[])} or {@link #String(byte[], String)} instead. 133 */ 134 @Deprecated String(byte[] data, int high)135 public String(byte[] data, int high) { 136 this(data, high, 0, data.length); 137 } 138 139 /** 140 * Converts a subsequence of the byte array to a string using the system's 141 * {@link java.nio.charset.Charset#defaultCharset default charset}. 142 * 143 * @throws NullPointerException 144 * if {@code data == null}. 145 * @throws IndexOutOfBoundsException 146 * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}. 147 */ String(byte[] data, int offset, int byteCount)148 public String(byte[] data, int offset, int byteCount) { 149 this(data, offset, byteCount, Charset.defaultCharset()); 150 } 151 152 /** 153 * Converts the byte array to a string, setting the high byte of every 154 * {@code char} to {@code high}. 155 * 156 * @throws NullPointerException 157 * if {@code data == null}. 158 * @throws IndexOutOfBoundsException 159 * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length} 160 * 161 * @deprecated Use {@link #String(byte[], int, int)} instead. 162 */ 163 @Deprecated String(byte[] data, int high, int offset, int byteCount)164 public String(byte[] data, int high, int offset, int byteCount) { 165 if ((offset | byteCount) < 0 || byteCount > data.length - offset) { 166 throw failedBoundsCheck(data.length, offset, byteCount); 167 } 168 this.offset = 0; 169 this.value = new char[byteCount]; 170 this.count = byteCount; 171 high <<= 8; 172 for (int i = 0; i < count; i++) { 173 value[i] = (char) (high + (data[offset++] & 0xff)); 174 } 175 } 176 177 /** 178 * Converts the byte array to a string using the named charset. 179 * 180 * <p>The behavior when the bytes cannot be decoded by the named charset 181 * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control. 182 * 183 * @throws NullPointerException 184 * if {@code data == null}. 185 * @throws IndexOutOfBoundsException 186 * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length}. 187 * @throws UnsupportedEncodingException 188 * if the named charset is not supported. 189 */ String(byte[] data, int offset, int byteCount, String charsetName)190 public String(byte[] data, int offset, int byteCount, String charsetName) throws UnsupportedEncodingException { 191 this(data, offset, byteCount, Charset.forNameUEE(charsetName)); 192 } 193 194 /** 195 * Converts the byte array to a string using the named charset. 196 * 197 * <p>The behavior when the bytes cannot be decoded by the named charset 198 * is unspecified. Use {@link java.nio.charset.CharsetDecoder} for more control. 199 * 200 * @throws NullPointerException 201 * if {@code data == null}. 202 * @throws UnsupportedEncodingException 203 * if {@code charsetName} is not supported. 204 */ String(byte[] data, String charsetName)205 public String(byte[] data, String charsetName) throws UnsupportedEncodingException { 206 this(data, 0, data.length, Charset.forNameUEE(charsetName)); 207 } 208 209 /** 210 * Converts the byte array to a string using the given charset. 211 * 212 * <p>The behavior when the bytes cannot be decoded by the given charset 213 * is to replace malformed input and unmappable code points with the charset's default 214 * replacement string. Use {@link java.nio.charset.CharsetDecoder} for more control. 215 * 216 * @throws IndexOutOfBoundsException 217 * if {@code byteCount < 0 || offset < 0 || offset + byteCount > data.length} 218 * @throws NullPointerException 219 * if {@code data == null} 220 * 221 * @since 1.6 222 */ String(byte[] data, int offset, int byteCount, Charset charset)223 public String(byte[] data, int offset, int byteCount, Charset charset) { 224 if ((offset | byteCount) < 0 || byteCount > data.length - offset) { 225 throw failedBoundsCheck(data.length, offset, byteCount); 226 } 227 228 // We inline UTF-8, ISO-8859-1, and US-ASCII decoders for speed and because 'count' and 229 // 'value' are final. 230 String canonicalCharsetName = charset.name(); 231 if (canonicalCharsetName.equals("UTF-8")) { 232 byte[] d = data; 233 char[] v = new char[byteCount]; 234 235 int idx = offset; 236 int last = offset + byteCount; 237 int s = 0; 238 outer: 239 while (idx < last) { 240 byte b0 = d[idx++]; 241 if ((b0 & 0x80) == 0) { 242 // 0xxxxxxx 243 // Range: U-00000000 - U-0000007F 244 int val = b0 & 0xff; 245 v[s++] = (char) val; 246 } else if (((b0 & 0xe0) == 0xc0) || ((b0 & 0xf0) == 0xe0) || 247 ((b0 & 0xf8) == 0xf0) || ((b0 & 0xfc) == 0xf8) || ((b0 & 0xfe) == 0xfc)) { 248 int utfCount = 1; 249 if ((b0 & 0xf0) == 0xe0) utfCount = 2; 250 else if ((b0 & 0xf8) == 0xf0) utfCount = 3; 251 else if ((b0 & 0xfc) == 0xf8) utfCount = 4; 252 else if ((b0 & 0xfe) == 0xfc) utfCount = 5; 253 254 // 110xxxxx (10xxxxxx)+ 255 // Range: U-00000080 - U-000007FF (count == 1) 256 // Range: U-00000800 - U-0000FFFF (count == 2) 257 // Range: U-00010000 - U-001FFFFF (count == 3) 258 // Range: U-00200000 - U-03FFFFFF (count == 4) 259 // Range: U-04000000 - U-7FFFFFFF (count == 5) 260 261 if (idx + utfCount > last) { 262 v[s++] = REPLACEMENT_CHAR; 263 continue; 264 } 265 266 // Extract usable bits from b0 267 int val = b0 & (0x1f >> (utfCount - 1)); 268 for (int i = 0; i < utfCount; ++i) { 269 byte b = d[idx++]; 270 if ((b & 0xc0) != 0x80) { 271 v[s++] = REPLACEMENT_CHAR; 272 idx--; // Put the input char back 273 continue outer; 274 } 275 // Push new bits in from the right side 276 val <<= 6; 277 val |= b & 0x3f; 278 } 279 280 // Note: Java allows overlong char 281 // specifications To disallow, check that val 282 // is greater than or equal to the minimum 283 // value for each count: 284 // 285 // count min value 286 // ----- ---------- 287 // 1 0x80 288 // 2 0x800 289 // 3 0x10000 290 // 4 0x200000 291 // 5 0x4000000 292 293 // Allow surrogate values (0xD800 - 0xDFFF) to 294 // be specified using 3-byte UTF values only 295 if ((utfCount != 2) && (val >= 0xD800) && (val <= 0xDFFF)) { 296 v[s++] = REPLACEMENT_CHAR; 297 continue; 298 } 299 300 // Reject chars greater than the Unicode maximum of U+10FFFF. 301 if (val > 0x10FFFF) { 302 v[s++] = REPLACEMENT_CHAR; 303 continue; 304 } 305 306 // Encode chars from U+10000 up as surrogate pairs 307 if (val < 0x10000) { 308 v[s++] = (char) val; 309 } else { 310 int x = val & 0xffff; 311 int u = (val >> 16) & 0x1f; 312 int w = (u - 1) & 0xffff; 313 int hi = 0xd800 | (w << 6) | (x >> 10); 314 int lo = 0xdc00 | (x & 0x3ff); 315 v[s++] = (char) hi; 316 v[s++] = (char) lo; 317 } 318 } else { 319 // Illegal values 0x8*, 0x9*, 0xa*, 0xb*, 0xfd-0xff 320 v[s++] = REPLACEMENT_CHAR; 321 } 322 } 323 324 if (s == byteCount) { 325 // We guessed right, so we can use our temporary array as-is. 326 this.offset = 0; 327 this.value = v; 328 this.count = s; 329 } else { 330 // Our temporary array was too big, so reallocate and copy. 331 this.offset = 0; 332 this.value = new char[s]; 333 this.count = s; 334 System.arraycopy(v, 0, value, 0, s); 335 } 336 } else if (canonicalCharsetName.equals("ISO-8859-1")) { 337 this.offset = 0; 338 this.value = new char[byteCount]; 339 this.count = byteCount; 340 Charsets.isoLatin1BytesToChars(data, offset, byteCount, value); 341 } else if (canonicalCharsetName.equals("US-ASCII")) { 342 this.offset = 0; 343 this.value = new char[byteCount]; 344 this.count = byteCount; 345 Charsets.asciiBytesToChars(data, offset, byteCount, value); 346 } else { 347 CharBuffer cb = charset.decode(ByteBuffer.wrap(data, offset, byteCount)); 348 this.offset = 0; 349 this.count = cb.length(); 350 if (count > 0) { 351 // We could use cb.array() directly, but that would mean we'd have to trust 352 // the CharsetDecoder doesn't hang on to the CharBuffer and mutate it later, 353 // which would break String's immutability guarantee. It would also tend to 354 // mean that we'd be wasting memory because CharsetDecoder doesn't trim the 355 // array. So we copy. 356 this.value = new char[count]; 357 System.arraycopy(cb.array(), 0, value, 0, count); 358 } else { 359 this.value = EmptyArray.CHAR; 360 } 361 } 362 } 363 364 /** 365 * Converts the byte array to a String using the given charset. 366 * 367 * @throws NullPointerException if {@code data == null} 368 * @since 1.6 369 */ String(byte[] data, Charset charset)370 public String(byte[] data, Charset charset) { 371 this(data, 0, data.length, charset); 372 } 373 374 /** 375 * Initializes this string to contain the given {@code char}s. 376 * Modifying the array after creating the string 377 * has no effect on the string. 378 * 379 * @throws NullPointerException if {@code data == null} 380 */ String(char[] data)381 public String(char[] data) { 382 this(data, 0, data.length); 383 } 384 385 /** 386 * Initializes this string to contain the given {@code char}s. 387 * Modifying the array after creating the string 388 * has no effect on the string. 389 * 390 * @throws NullPointerException 391 * if {@code data == null}. 392 * @throws IndexOutOfBoundsException 393 * if {@code charCount < 0 || offset < 0 || offset + charCount > data.length} 394 */ String(char[] data, int offset, int charCount)395 public String(char[] data, int offset, int charCount) { 396 if ((offset | charCount) < 0 || charCount > data.length - offset) { 397 throw failedBoundsCheck(data.length, offset, charCount); 398 } 399 this.offset = 0; 400 this.value = new char[charCount]; 401 this.count = charCount; 402 System.arraycopy(data, offset, value, 0, count); 403 } 404 405 /* 406 * Internal version of the String(char[], int, int) constructor. 407 * Does not range check, null check, or copy the array. 408 */ String(int offset, int charCount, char[] chars)409 String(int offset, int charCount, char[] chars) { 410 this.value = chars; 411 this.offset = offset; 412 this.count = charCount; 413 } 414 415 /** 416 * Constructs a copy of the given string. 417 * The returned string's <a href="#backing_array">backing array</a> 418 * is no larger than necessary. 419 */ String(String toCopy)420 public String(String toCopy) { 421 value = (toCopy.value.length == toCopy.count) 422 ? toCopy.value 423 : Arrays.copyOfRange(toCopy.value, toCopy.offset, toCopy.offset + toCopy.length()); 424 offset = 0; 425 count = value.length; 426 } 427 428 /** 429 * Creates a {@code String} from the contents of the specified 430 * {@code StringBuffer}. 431 */ String(StringBuffer stringBuffer)432 public String(StringBuffer stringBuffer) { 433 offset = 0; 434 synchronized (stringBuffer) { 435 value = stringBuffer.shareValue(); 436 count = stringBuffer.length(); 437 } 438 } 439 440 /** 441 * Creates a {@code String} from the sub-array of Unicode code points. 442 * 443 * @throws NullPointerException 444 * if {@code codePoints == null}. 445 * @throws IllegalArgumentException 446 * if any of the elements of {@code codePoints} are not valid 447 * Unicode code points. 448 * @throws IndexOutOfBoundsException 449 * if {@code offset} or {@code count} are not within the bounds 450 * of {@code codePoints}. 451 * @since 1.5 452 */ String(int[] codePoints, int offset, int count)453 public String(int[] codePoints, int offset, int count) { 454 if (codePoints == null) { 455 throw new NullPointerException("codePoints == null"); 456 } 457 if ((offset | count) < 0 || count > codePoints.length - offset) { 458 throw failedBoundsCheck(codePoints.length, offset, count); 459 } 460 this.offset = 0; 461 this.value = new char[count * 2]; 462 int end = offset + count; 463 int c = 0; 464 for (int i = offset; i < end; i++) { 465 c += Character.toChars(codePoints[i], this.value, c); 466 } 467 this.count = c; 468 } 469 470 /** 471 * Creates a {@code String} from the contents of the specified {@code 472 * StringBuilder}. 473 * 474 * @throws NullPointerException 475 * if {@code stringBuilder == null}. 476 * @since 1.5 477 */ String(StringBuilder stringBuilder)478 public String(StringBuilder stringBuilder) { 479 if (stringBuilder == null) { 480 throw new NullPointerException("stringBuilder == null"); 481 } 482 this.offset = 0; 483 this.count = stringBuilder.length(); 484 this.value = new char[this.count]; 485 stringBuilder.getChars(0, this.count, this.value, 0); 486 } 487 488 /** 489 * Returns the {@code char} at {@code index}. 490 * @throws IndexOutOfBoundsException if {@code index < 0} or {@code index >= length()}. 491 */ charAt(int index)492 public char charAt(int index) { 493 if (index < 0 || index >= count) { 494 throw indexAndLength(index); 495 } 496 return value[offset + index]; 497 } 498 indexAndLength(int index)499 private StringIndexOutOfBoundsException indexAndLength(int index) { 500 throw new StringIndexOutOfBoundsException(this, index); 501 } 502 startEndAndLength(int start, int end)503 private StringIndexOutOfBoundsException startEndAndLength(int start, int end) { 504 throw new StringIndexOutOfBoundsException(this, start, end - start); 505 } 506 failedBoundsCheck(int arrayLength, int offset, int count)507 private StringIndexOutOfBoundsException failedBoundsCheck(int arrayLength, int offset, int count) { 508 throw new StringIndexOutOfBoundsException(arrayLength, offset, count); 509 } 510 511 /** 512 * This isn't equivalent to either of ICU's u_foldCase case folds, and thus any of the Unicode 513 * case folds, but it's what the RI uses. 514 */ foldCase(char ch)515 private char foldCase(char ch) { 516 if (ch < 128) { 517 if ('A' <= ch && ch <= 'Z') { 518 return (char) (ch + ('a' - 'A')); 519 } 520 return ch; 521 } 522 return Character.toLowerCase(Character.toUpperCase(ch)); 523 } 524 525 /** 526 * Compares this string to the given string. 527 * 528 * <p>The strings are compared one {@code char} at a time. 529 * In the discussion of the return value below, note that {@code char} does not 530 * mean code point, though this should only be visible for surrogate pairs. 531 * 532 * <p>If there is an index at which the two strings differ, the result is 533 * the difference between the two {@code char}s at the lowest such index. 534 * If not, but the lengths of the strings differ, the result is the difference 535 * between the two strings' lengths. 536 * If the strings are the same length and every {@code char} is the same, the result is 0. 537 * 538 * @throws NullPointerException 539 * if {@code string} is {@code null}. 540 */ compareTo(String string)541 public native int compareTo(String string); 542 543 /** 544 * Compares this string to the given string, ignoring case differences. 545 * 546 * <p>The strings are compared one {@code char} at a time. This is not suitable 547 * for case-insensitive string comparison for all locales. 548 * Use a {@link java.text.Collator} instead. 549 * 550 * <p>If there is an index at which the two strings differ, the result is 551 * the difference between the two {@code char}s at the lowest such index. 552 * If not, but the lengths of the strings differ, the result is the difference 553 * between the two strings' lengths. 554 * If the strings are the same length and every {@code char} is the same, the result is 0. 555 * 556 * @throws NullPointerException 557 * if {@code string} is {@code null}. 558 */ compareToIgnoreCase(String string)559 public int compareToIgnoreCase(String string) { 560 int o1 = offset, o2 = string.offset, result; 561 int end = offset + (count < string.count ? count : string.count); 562 char c1, c2; 563 char[] target = string.value; 564 while (o1 < end) { 565 if ((c1 = value[o1++]) == (c2 = target[o2++])) { 566 continue; 567 } 568 c1 = foldCase(c1); 569 c2 = foldCase(c2); 570 if ((result = c1 - c2) != 0) { 571 return result; 572 } 573 } 574 return count - string.count; 575 } 576 577 /** 578 * Concatenates this string and the specified string. 579 * 580 * @param string 581 * the string to concatenate 582 * @return a new string which is the concatenation of this string and the 583 * specified string. 584 */ concat(String string)585 public String concat(String string) { 586 if (string.count > 0 && count > 0) { 587 char[] buffer = new char[count + string.count]; 588 System.arraycopy(value, offset, buffer, 0, count); 589 System.arraycopy(string.value, string.offset, buffer, count, string.count); 590 return new String(0, buffer.length, buffer); 591 } 592 return count == 0 ? string : this; 593 } 594 595 /** 596 * Creates a new string by copying the given {@code char[]}. 597 * Modifying the array after creating the string has no 598 * effect on the string. 599 * 600 * @throws NullPointerException 601 * if {@code data} is {@code null}. 602 */ copyValueOf(char[] data)603 public static String copyValueOf(char[] data) { 604 return new String(data, 0, data.length); 605 } 606 607 /** 608 * Creates a new string by copying the given subsequence of the given {@code char[]}. 609 * Modifying the array after creating the string has no 610 * effect on the string. 611 612 * @throws NullPointerException 613 * if {@code data} is {@code null}. 614 * @throws IndexOutOfBoundsException 615 * if {@code length < 0, start < 0} or {@code start + length > 616 * data.length}. 617 */ copyValueOf(char[] data, int start, int length)618 public static String copyValueOf(char[] data, int start, int length) { 619 return new String(data, start, length); 620 } 621 622 /** 623 * Compares the specified string to this string to determine if the 624 * specified string is a suffix. 625 * 626 * @throws NullPointerException 627 * if {@code suffix} is {@code null}. 628 */ endsWith(String suffix)629 public boolean endsWith(String suffix) { 630 return regionMatches(count - suffix.count, suffix, 0, suffix.count); 631 } 632 633 /** 634 * Compares the given object to this string and returns true if they are 635 * equal. The object must be an instance of {@code String} with the same length, 636 * where for every index, {@code charAt} on each string returns the same value. 637 */ equals(Object other)638 @Override public boolean equals(Object other) { 639 if (other == this) { 640 return true; 641 } 642 if (other instanceof String) { 643 String s = (String)other; 644 int count = this.count; 645 if (s.count != count) { 646 return false; 647 } 648 // TODO: we want to avoid many boundchecks in the loop below 649 // for long Strings until we have array equality intrinsic. 650 // Bad benchmarks just push .equals without first getting a 651 // hashCode hit (unlike real world use in a Hashtable). Filter 652 // out these long strings here. When we get the array equality 653 // intrinsic then remove this use of hashCode. 654 if (hashCode() != s.hashCode()) { 655 return false; 656 } 657 char[] value1 = value; 658 int offset1 = offset; 659 char[] value2 = s.value; 660 int offset2 = s.offset; 661 for (int end = offset1 + count; offset1 < end; ) { 662 if (value1[offset1] != value2[offset2]) { 663 return false; 664 } 665 offset1++; 666 offset2++; 667 } 668 return true; 669 } else { 670 return false; 671 } 672 } 673 674 /** 675 * Compares the given string to this string ignoring case. 676 * 677 * <p>The strings are compared one {@code char} at a time. This is not suitable 678 * for case-insensitive string comparison for all locales. 679 * Use a {@link java.text.Collator} instead. 680 */ 681 @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ") equalsIgnoreCase(String string)682 public boolean equalsIgnoreCase(String string) { 683 if (string == this) { 684 return true; 685 } 686 if (string == null || count != string.count) { 687 return false; 688 } 689 int o1 = offset, o2 = string.offset; 690 int end = offset + count; 691 char[] target = string.value; 692 while (o1 < end) { 693 char c1 = value[o1++]; 694 char c2 = target[o2++]; 695 if (c1 != c2 && foldCase(c1) != foldCase(c2)) { 696 return false; 697 } 698 } 699 return true; 700 } 701 702 /** 703 * Mangles a subsequence of this string into a byte array by stripping the high order bits from 704 * each {@code char}. Use {@link #getBytes()} or {@link #getBytes(String)} instead. 705 * 706 * @param start 707 * the start offset in this string. 708 * @param end 709 * the end+1 offset in this string. 710 * @param data 711 * the destination byte array. 712 * @param index 713 * the start offset in the destination byte array. 714 * @throws NullPointerException 715 * if {@code data} is {@code null}. 716 * @throws IndexOutOfBoundsException 717 * if {@code start < 0}, {@code end > length()}, {@code index < 718 * 0} or {@code end - start > data.length - index}. 719 * @deprecated Use {@link #getBytes()} or {@link #getBytes(String)} 720 */ 721 @Deprecated getBytes(int start, int end, byte[] data, int index)722 public void getBytes(int start, int end, byte[] data, int index) { 723 if (start >= 0 && start <= end && end <= count) { 724 end += offset; 725 try { 726 for (int i = offset + start; i < end; i++) { 727 data[index++] = (byte) value[i]; 728 } 729 } catch (ArrayIndexOutOfBoundsException ignored) { 730 throw failedBoundsCheck(data.length, index, end - start); 731 } 732 } else { 733 throw startEndAndLength(start, end); 734 } 735 } 736 737 /** 738 * Returns a new byte array containing the code points in this string encoded using the 739 * system's {@link java.nio.charset.Charset#defaultCharset default charset}. 740 * 741 * <p>The behavior when this string cannot be represented in the system's default charset 742 * is unspecified. In practice, when the default charset is UTF-8 (as it is on Android), 743 * all strings can be encoded. 744 */ getBytes()745 public byte[] getBytes() { 746 return getBytes(Charset.defaultCharset()); 747 } 748 749 /** 750 * Returns a new byte array containing the code points of this string encoded using the 751 * named charset. 752 * 753 * <p>The behavior when this string cannot be represented in the named charset 754 * is unspecified. Use {@link java.nio.charset.CharsetEncoder} for more control. 755 * 756 * @throws UnsupportedEncodingException if the charset is not supported 757 */ getBytes(String charsetName)758 public byte[] getBytes(String charsetName) throws UnsupportedEncodingException { 759 return getBytes(Charset.forNameUEE(charsetName)); 760 } 761 762 /** 763 * Returns a new byte array containing the code points of this string encoded using the 764 * given charset. 765 * 766 * <p>The behavior when this string cannot be represented in the given charset 767 * is to replace malformed input and unmappable code points with the charset's default 768 * replacement byte array. Use {@link java.nio.charset.CharsetEncoder} for more control. 769 * 770 * @since 1.6 771 */ getBytes(Charset charset)772 public byte[] getBytes(Charset charset) { 773 String canonicalCharsetName = charset.name(); 774 if (canonicalCharsetName.equals("UTF-8")) { 775 return Charsets.toUtf8Bytes(value, offset, count); 776 } else if (canonicalCharsetName.equals("ISO-8859-1")) { 777 return Charsets.toIsoLatin1Bytes(value, offset, count); 778 } else if (canonicalCharsetName.equals("US-ASCII")) { 779 return Charsets.toAsciiBytes(value, offset, count); 780 } else if (canonicalCharsetName.equals("UTF-16BE")) { 781 return Charsets.toBigEndianUtf16Bytes(value, offset, count); 782 } else { 783 CharBuffer chars = CharBuffer.wrap(this.value, this.offset, this.count); 784 ByteBuffer buffer = charset.encode(chars.asReadOnlyBuffer()); 785 byte[] bytes = new byte[buffer.limit()]; 786 buffer.get(bytes); 787 return bytes; 788 } 789 } 790 791 /** 792 * Copies the given subsequence of this string to the given array 793 * starting at the given offset. 794 * 795 * @param start 796 * the start offset in this string. 797 * @param end 798 * the end+1 offset in this string. 799 * @param buffer 800 * the destination array. 801 * @param index 802 * the start offset in the destination array. 803 * @throws NullPointerException 804 * if {@code buffer} is {@code null}. 805 * @throws IndexOutOfBoundsException 806 * if {@code start < 0}, {@code end > length()}, {@code start > 807 * end}, {@code index < 0}, {@code end - start > buffer.length - 808 * index} 809 */ getChars(int start, int end, char[] buffer, int index)810 public void getChars(int start, int end, char[] buffer, int index) { 811 if (start >= 0 && start <= end && end <= count) { 812 System.arraycopy(value, start + offset, buffer, index, end - start); 813 } else { 814 // We throw StringIndexOutOfBoundsException rather than System.arraycopy's AIOOBE. 815 throw startEndAndLength(start, end); 816 } 817 } 818 819 /** 820 * getChars without bounds checks, for use by other classes 821 * within the java.lang package only. The caller is responsible for 822 * ensuring that start >= 0 && start <= end && end <= count. 823 */ _getChars(int start, int end, char[] buffer, int index)824 void _getChars(int start, int end, char[] buffer, int index) { 825 System.arraycopy(value, start + offset, buffer, index, end - start); 826 } 827 hashCode()828 @Override public int hashCode() { 829 int hash = hashCode; 830 if (hash == 0) { 831 if (count == 0) { 832 return 0; 833 } 834 final int end = count + offset; 835 final char[] chars = value; 836 for (int i = offset; i < end; ++i) { 837 hash = 31*hash + chars[i]; 838 } 839 hashCode = hash; 840 } 841 return hash; 842 } 843 844 /** 845 * Returns the first index of the given code point, or -1. 846 * The search starts at the beginning and moves towards 847 * the end of this string. 848 */ indexOf(int c)849 public int indexOf(int c) { 850 // TODO: just "return indexOf(c, 0);" when the JIT can inline that deep. 851 if (c > 0xffff) { 852 return indexOfSupplementary(c, 0); 853 } 854 return fastIndexOf(c, 0); 855 } 856 857 /** 858 * Returns the next index of the given code point, or -1. The 859 * search starts at the given offset and moves towards 860 * the end of this string. 861 */ indexOf(int c, int start)862 public int indexOf(int c, int start) { 863 if (c > 0xffff) { 864 return indexOfSupplementary(c, start); 865 } 866 return fastIndexOf(c, start); 867 } 868 fastIndexOf(int c, int start)869 private native int fastIndexOf(int c, int start); 870 indexOfSupplementary(int c, int start)871 private int indexOfSupplementary(int c, int start) { 872 if (!Character.isSupplementaryCodePoint(c)) { 873 return -1; 874 } 875 char[] chars = Character.toChars(c); 876 String needle = new String(0, chars.length, chars); 877 return indexOf(needle, start); 878 } 879 880 /** 881 * Returns the first index of the given string, or -1. The 882 * search starts at the beginning and moves towards the end 883 * of this string. 884 * 885 * @throws NullPointerException 886 * if {@code string} is {@code null}. 887 */ indexOf(String string)888 public int indexOf(String string) { 889 int start = 0; 890 int subCount = string.count; 891 int _count = count; 892 if (subCount > 0) { 893 if (subCount > _count) { 894 return -1; 895 } 896 char[] target = string.value; 897 int subOffset = string.offset; 898 char firstChar = target[subOffset]; 899 int end = subOffset + subCount; 900 while (true) { 901 int i = indexOf(firstChar, start); 902 if (i == -1 || subCount + i > _count) { 903 return -1; // handles subCount > count || start >= count 904 } 905 int o1 = offset + i, o2 = subOffset; 906 char[] _value = value; 907 while (++o2 < end && _value[++o1] == target[o2]) { 908 // Intentionally empty 909 } 910 if (o2 == end) { 911 return i; 912 } 913 start = i + 1; 914 } 915 } 916 return start < _count ? start : _count; 917 } 918 919 /** 920 * Returns the next index of the given string in this string, or -1. The search 921 * for the string starts at the given offset and moves towards the end 922 * of this string. 923 * 924 * @throws NullPointerException 925 * if {@code subString} is {@code null}. 926 */ indexOf(String subString, int start)927 public int indexOf(String subString, int start) { 928 if (start < 0) { 929 start = 0; 930 } 931 int subCount = subString.count; 932 int _count = count; 933 if (subCount > 0) { 934 if (subCount + start > _count) { 935 return -1; 936 } 937 char[] target = subString.value; 938 int subOffset = subString.offset; 939 char firstChar = target[subOffset]; 940 int end = subOffset + subCount; 941 while (true) { 942 int i = indexOf(firstChar, start); 943 if (i == -1 || subCount + i > _count) { 944 return -1; // handles subCount > count || start >= count 945 } 946 int o1 = offset + i, o2 = subOffset; 947 char[] _value = value; 948 while (++o2 < end && _value[++o1] == target[o2]) { 949 // Intentionally empty 950 } 951 if (o2 == end) { 952 return i; 953 } 954 start = i + 1; 955 } 956 } 957 return start < _count ? start : _count; 958 } 959 960 /** 961 * Returns an interned string equal to this string. The VM maintains an internal set of 962 * unique strings. All string literals found in loaded classes' 963 * constant pools are automatically interned. Manually-interned strings are only weakly 964 * referenced, so calling {@code intern} won't lead to unwanted retention. 965 * 966 * <p>Interning is typically used because it guarantees that for interned strings 967 * {@code a} and {@code b}, {@code a.equals(b)} can be simplified to 968 * {@code a == b}. (This is not true of non-interned strings.) 969 * 970 * <p>Many applications find it simpler and more convenient to use an explicit 971 * {@link java.util.HashMap} to implement their own pools. 972 */ intern()973 public native String intern(); 974 975 /** 976 * Returns true if the length of this string is 0. 977 * 978 * @since 1.6 979 */ isEmpty()980 public boolean isEmpty() { 981 return count == 0; 982 } 983 984 /** 985 * Returns the last index of the code point {@code c}, or -1. 986 * The search starts at the end and moves towards the 987 * beginning of this string. 988 */ lastIndexOf(int c)989 public int lastIndexOf(int c) { 990 if (c > 0xffff) { 991 return lastIndexOfSupplementary(c, Integer.MAX_VALUE); 992 } 993 int _count = count; 994 int _offset = offset; 995 char[] _value = value; 996 for (int i = _offset + _count - 1; i >= _offset; --i) { 997 if (_value[i] == c) { 998 return i - _offset; 999 } 1000 } 1001 return -1; 1002 } 1003 1004 /** 1005 * Returns the last index of the code point {@code c}, or -1. 1006 * The search starts at offset {@code start} and moves towards 1007 * the beginning of this string. 1008 */ lastIndexOf(int c, int start)1009 public int lastIndexOf(int c, int start) { 1010 if (c > 0xffff) { 1011 return lastIndexOfSupplementary(c, start); 1012 } 1013 int _count = count; 1014 int _offset = offset; 1015 char[] _value = value; 1016 if (start >= 0) { 1017 if (start >= _count) { 1018 start = _count - 1; 1019 } 1020 for (int i = _offset + start; i >= _offset; --i) { 1021 if (_value[i] == c) { 1022 return i - _offset; 1023 } 1024 } 1025 } 1026 return -1; 1027 } 1028 lastIndexOfSupplementary(int c, int start)1029 private int lastIndexOfSupplementary(int c, int start) { 1030 if (!Character.isSupplementaryCodePoint(c)) { 1031 return -1; 1032 } 1033 char[] chars = Character.toChars(c); 1034 String needle = new String(0, chars.length, chars); 1035 return lastIndexOf(needle, start); 1036 } 1037 1038 /** 1039 * Returns the index of the start of the last match for the given string in this string, or -1. 1040 * The search for the string starts at the end and moves towards the beginning 1041 * of this string. 1042 * 1043 * @throws NullPointerException 1044 * if {@code string} is {@code null}. 1045 */ lastIndexOf(String string)1046 public int lastIndexOf(String string) { 1047 // Use count instead of count - 1 so lastIndexOf("") returns count 1048 return lastIndexOf(string, count); 1049 } 1050 1051 /** 1052 * Returns the index of the start of the previous match for the given string in this string, 1053 * or -1. 1054 * The search for the string starts at the given index and moves towards the beginning 1055 * of this string. 1056 * 1057 * @throws NullPointerException 1058 * if {@code subString} is {@code null}. 1059 */ lastIndexOf(String subString, int start)1060 public int lastIndexOf(String subString, int start) { 1061 int subCount = subString.count; 1062 if (subCount <= count && start >= 0) { 1063 if (subCount > 0) { 1064 if (start > count - subCount) { 1065 start = count - subCount; 1066 } 1067 // count and subCount are both >= 1 1068 char[] target = subString.value; 1069 int subOffset = subString.offset; 1070 char firstChar = target[subOffset]; 1071 int end = subOffset + subCount; 1072 while (true) { 1073 int i = lastIndexOf(firstChar, start); 1074 if (i == -1) { 1075 return -1; 1076 } 1077 int o1 = offset + i, o2 = subOffset; 1078 while (++o2 < end && value[++o1] == target[o2]) { 1079 // Intentionally empty 1080 } 1081 if (o2 == end) { 1082 return i; 1083 } 1084 start = i - 1; 1085 } 1086 } 1087 return start < count ? start : count; 1088 } 1089 return -1; 1090 } 1091 1092 /** 1093 * Returns the number of {@code char}s in this string. If this string contains surrogate pairs, 1094 * this is not the same as the number of code points. 1095 */ length()1096 public int length() { 1097 return count; 1098 } 1099 1100 /** 1101 * Returns true if the given subsequence of the given string matches this string starting 1102 * at the given offset. 1103 * 1104 * @param thisStart the start offset in this string. 1105 * @param string the other string. 1106 * @param start the start offset in {@code string}. 1107 * @param length the number of {@code char}s to compare. 1108 * @throws NullPointerException 1109 * if {@code string} is {@code null}. 1110 */ regionMatches(int thisStart, String string, int start, int length)1111 public boolean regionMatches(int thisStart, String string, int start, int length) { 1112 if (string == null) { 1113 throw new NullPointerException("string == null"); 1114 } 1115 if (start < 0 || string.count - start < length) { 1116 return false; 1117 } 1118 if (thisStart < 0 || count - thisStart < length) { 1119 return false; 1120 } 1121 if (length <= 0) { 1122 return true; 1123 } 1124 int o1 = offset + thisStart, o2 = string.offset + start; 1125 char[] value1 = value; 1126 char[] value2 = string.value; 1127 for (int i = 0; i < length; ++i) { 1128 if (value1[o1 + i] != value2[o2 + i]) { 1129 return false; 1130 } 1131 } 1132 return true; 1133 } 1134 1135 /** 1136 * Returns true if the given subsequence of the given string matches this string starting 1137 * at the given offset. 1138 * 1139 * <p>If ignoreCase is true, case is ignored during the comparison. 1140 * The strings are compared one {@code char} at a time. This is not suitable 1141 * for case-insensitive string comparison for all locales. 1142 * Use a {@link java.text.Collator} instead. 1143 * 1144 * @param ignoreCase 1145 * specifies if case should be ignored (use {@link java.text.Collator} instead for 1146 * non-ASCII case insensitivity). 1147 * @param thisStart the start offset in this string. 1148 * @param string the other string. 1149 * @param start the start offset in {@code string}. 1150 * @param length the number of {@code char}s to compare. 1151 * @throws NullPointerException 1152 * if {@code string} is {@code null}. 1153 */ regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length)1154 public boolean regionMatches(boolean ignoreCase, int thisStart, String string, int start, int length) { 1155 if (!ignoreCase) { 1156 return regionMatches(thisStart, string, start, length); 1157 } 1158 if (string == null) { 1159 throw new NullPointerException("string == null"); 1160 } 1161 if (thisStart < 0 || length > count - thisStart) { 1162 return false; 1163 } 1164 if (start < 0 || length > string.count - start) { 1165 return false; 1166 } 1167 thisStart += offset; 1168 start += string.offset; 1169 int end = thisStart + length; 1170 char[] target = string.value; 1171 while (thisStart < end) { 1172 char c1 = value[thisStart++]; 1173 char c2 = target[start++]; 1174 if (c1 != c2 && foldCase(c1) != foldCase(c2)) { 1175 return false; 1176 } 1177 } 1178 return true; 1179 } 1180 1181 /** 1182 * Returns a copy of this string after replacing occurrences of the given {@code char} with another. 1183 */ replace(char oldChar, char newChar)1184 public String replace(char oldChar, char newChar) { 1185 char[] buffer = value; 1186 int _offset = offset; 1187 int _count = count; 1188 1189 int idx = _offset; 1190 int last = _offset + _count; 1191 boolean copied = false; 1192 while (idx < last) { 1193 if (buffer[idx] == oldChar) { 1194 if (!copied) { 1195 char[] newBuffer = new char[_count]; 1196 System.arraycopy(buffer, _offset, newBuffer, 0, _count); 1197 buffer = newBuffer; 1198 idx -= _offset; 1199 last -= _offset; 1200 copied = true; 1201 } 1202 buffer[idx] = newChar; 1203 } 1204 idx++; 1205 } 1206 1207 return copied ? new String(0, count, buffer) : this; 1208 } 1209 1210 /** 1211 * Returns a copy of this string after replacing occurrences of {@code target} replaced 1212 * with {@code replacement}. The string is processed from the beginning to the 1213 * end. 1214 * 1215 * @throws NullPointerException 1216 * if {@code target} or {@code replacement} is {@code null}. 1217 */ replace(CharSequence target, CharSequence replacement)1218 public String replace(CharSequence target, CharSequence replacement) { 1219 if (target == null) { 1220 throw new NullPointerException("target == null"); 1221 } 1222 if (replacement == null) { 1223 throw new NullPointerException("replacement == null"); 1224 } 1225 1226 String targetString = target.toString(); 1227 int matchStart = indexOf(targetString, 0); 1228 if (matchStart == -1) { 1229 // If there's nothing to replace, return the original string untouched. 1230 return this; 1231 } 1232 1233 String replacementString = replacement.toString(); 1234 1235 // The empty target matches at the start and end and between each char. 1236 int targetLength = targetString.length(); 1237 if (targetLength == 0) { 1238 // The result contains the original 'count' chars, a copy of the 1239 // replacement string before every one of those chars, and a final 1240 // copy of the replacement string at the end. 1241 int resultLength = count + (count + 1) * replacementString.length(); 1242 StringBuilder result = new StringBuilder(resultLength); 1243 result.append(replacementString); 1244 int end = offset + count; 1245 for (int i = offset; i != end; ++i) { 1246 result.append(value[i]); 1247 result.append(replacementString); 1248 } 1249 return result.toString(); 1250 } 1251 1252 StringBuilder result = new StringBuilder(count); 1253 int searchStart = 0; 1254 do { 1255 // Copy chars before the match... 1256 result.append(value, offset + searchStart, matchStart - searchStart); 1257 // Insert the replacement... 1258 result.append(replacementString); 1259 // And skip over the match... 1260 searchStart = matchStart + targetLength; 1261 } while ((matchStart = indexOf(targetString, searchStart)) != -1); 1262 // Copy any trailing chars... 1263 result.append(value, offset + searchStart, count - searchStart); 1264 return result.toString(); 1265 } 1266 1267 /** 1268 * Compares the specified string to this string to determine if the 1269 * specified string is a prefix. 1270 * 1271 * @param prefix 1272 * the string to look for. 1273 * @return {@code true} if the specified string is a prefix of this string, 1274 * {@code false} otherwise 1275 * @throws NullPointerException 1276 * if {@code prefix} is {@code null}. 1277 */ startsWith(String prefix)1278 public boolean startsWith(String prefix) { 1279 return startsWith(prefix, 0); 1280 } 1281 1282 /** 1283 * Compares the specified string to this string, starting at the specified 1284 * offset, to determine if the specified string is a prefix. 1285 * 1286 * @param prefix 1287 * the string to look for. 1288 * @param start 1289 * the starting offset. 1290 * @return {@code true} if the specified string occurs in this string at the 1291 * specified offset, {@code false} otherwise. 1292 * @throws NullPointerException 1293 * if {@code prefix} is {@code null}. 1294 */ startsWith(String prefix, int start)1295 public boolean startsWith(String prefix, int start) { 1296 return regionMatches(start, prefix, 0, prefix.count); 1297 } 1298 1299 /** 1300 * Returns a string containing a suffix of this string starting at {@code start}. 1301 * The returned string shares this string's <a href="#backing_array">backing array</a>. 1302 * 1303 * @throws IndexOutOfBoundsException 1304 * if {@code start < 0} or {@code start > length()}. 1305 */ substring(int start)1306 public String substring(int start) { 1307 if (start == 0) { 1308 return this; 1309 } 1310 if (start >= 0 && start <= count) { 1311 return new String(offset + start, count - start, value); 1312 } 1313 throw indexAndLength(start); 1314 } 1315 1316 /** 1317 * Returns a string containing the given subsequence of this string. 1318 * The returned string shares this string's <a href="#backing_array">backing array</a>. 1319 * 1320 * @param start the start offset. 1321 * @param end the end+1 offset. 1322 * @throws IndexOutOfBoundsException 1323 * if {@code start < 0}, {@code start > end} or {@code end > length()}. 1324 */ substring(int start, int end)1325 public String substring(int start, int end) { 1326 if (start == 0 && end == count) { 1327 return this; 1328 } 1329 // Fast range check. 1330 if (start >= 0 && start <= end && end <= count) { 1331 return new String(offset + start, end - start, value); 1332 } 1333 throw startEndAndLength(start, end); 1334 } 1335 1336 /** 1337 * Returns a new {@code char} array containing a copy of the {@code char}s in this string. 1338 * This is expensive and rarely useful. If you just want to iterate over the {@code char}s in 1339 * the string, use {@link #charAt} instead. 1340 */ toCharArray()1341 public char[] toCharArray() { 1342 char[] buffer = new char[count]; 1343 System.arraycopy(value, offset, buffer, 0, count); 1344 return buffer; 1345 } 1346 1347 /** 1348 * Converts this string to lower case, using the rules of the user's default locale. 1349 * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 1350 * 1351 * @return a new lower case string, or {@code this} if it's already all lower case. 1352 */ toLowerCase()1353 public String toLowerCase() { 1354 return CaseMapper.toLowerCase(Locale.getDefault(), this, value, offset, count); 1355 } 1356 1357 /** 1358 * Converts this string to lower case, using the rules of {@code locale}. 1359 * 1360 * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include 1361 * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in 1362 * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get 1363 * correct case mapping of Greek characters: any locale will do. 1364 * 1365 * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a> 1366 * for full details of context- and language-specific special cases. 1367 * 1368 * @return a new lower case string, or {@code this} if it's already all lower case. 1369 */ toLowerCase(Locale locale)1370 public String toLowerCase(Locale locale) { 1371 return CaseMapper.toLowerCase(locale, this, value, offset, count); 1372 } 1373 1374 /** 1375 * Returns this string. 1376 */ 1377 @Override toString()1378 public String toString() { 1379 return this; 1380 } 1381 1382 /** 1383 * Converts this this string to upper case, using the rules of the user's default locale. 1384 * See "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 1385 * 1386 * @return a new upper case string, or {@code this} if it's already all upper case. 1387 */ toUpperCase()1388 public String toUpperCase() { 1389 return CaseMapper.toUpperCase(Locale.getDefault(), this, value, offset, count); 1390 } 1391 1392 /** 1393 * Converts this this string to upper case, using the rules of {@code locale}. 1394 * 1395 * <p>Most case mappings are unaffected by the language of a {@code Locale}. Exceptions include 1396 * dotted and dotless I in Azeri and Turkish locales, and dotted and dotless I and J in 1397 * Lithuanian locales. On the other hand, it isn't necessary to provide a Greek locale to get 1398 * correct case mapping of Greek characters: any locale will do. 1399 * 1400 * <p>See <a href="http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt">http://www.unicode.org/Public/UNIDATA/SpecialCasing.txt</a> 1401 * for full details of context- and language-specific special cases. 1402 * 1403 * @return a new upper case string, or {@code this} if it's already all upper case. 1404 */ toUpperCase(Locale locale)1405 public String toUpperCase(Locale locale) { 1406 return CaseMapper.toUpperCase(locale, this, value, offset, count); 1407 } 1408 1409 /** 1410 * Returns a string with no code points <code><= \\u0020</code> at 1411 * the beginning or end. 1412 */ trim()1413 public String trim() { 1414 int start = offset, last = offset + count - 1; 1415 int end = last; 1416 while ((start <= end) && (value[start] <= ' ')) { 1417 start++; 1418 } 1419 while ((end >= start) && (value[end] <= ' ')) { 1420 end--; 1421 } 1422 if (start == offset && end == last) { 1423 return this; 1424 } 1425 return new String(start, end - start + 1, value); 1426 } 1427 1428 /** 1429 * Returns a new string containing the same {@code char}s as the given 1430 * array. Modifying the array after creating the string has no 1431 * effect on the string. 1432 * 1433 * @throws NullPointerException 1434 * if {@code data} is {@code null}. 1435 */ valueOf(char[] data)1436 public static String valueOf(char[] data) { 1437 return new String(data, 0, data.length); 1438 } 1439 1440 /** 1441 * Returns a new string containing the same {@code char}s as the given 1442 * subset of the given array. Modifying the array after creating the string has no 1443 * effect on the string. 1444 * 1445 * @throws IndexOutOfBoundsException 1446 * if {@code length < 0}, {@code start < 0} or {@code start + length > data.length} 1447 * @throws NullPointerException 1448 * if {@code data} is {@code null}. 1449 */ valueOf(char[] data, int start, int length)1450 public static String valueOf(char[] data, int start, int length) { 1451 return new String(data, start, length); 1452 } 1453 1454 /** 1455 * Returns a new string of just the given {@code char}. 1456 */ valueOf(char value)1457 public static String valueOf(char value) { 1458 String s; 1459 if (value < 128) { 1460 s = new String(value, 1, ASCII); 1461 } else { 1462 s = new String(0, 1, new char[] { value }); 1463 } 1464 s.hashCode = value; 1465 return s; 1466 } 1467 1468 /** 1469 * Returns the string representation of the given double. 1470 */ valueOf(double value)1471 public static String valueOf(double value) { 1472 return Double.toString(value); 1473 } 1474 1475 /** 1476 * Returns the string representation of the given float. 1477 */ valueOf(float value)1478 public static String valueOf(float value) { 1479 return Float.toString(value); 1480 } 1481 1482 /** 1483 * Returns the string representation of the given int. 1484 */ valueOf(int value)1485 public static String valueOf(int value) { 1486 return Integer.toString(value); 1487 } 1488 1489 /** 1490 * Returns the string representation of the given long. 1491 */ valueOf(long value)1492 public static String valueOf(long value) { 1493 return Long.toString(value); 1494 } 1495 1496 /** 1497 * Converts the specified object to its string representation. If the object 1498 * is null return the string {@code "null"}, otherwise use {@code 1499 * toString()} to get the string representation. 1500 * 1501 * @param value 1502 * the object. 1503 * @return the object converted to a string, or the string {@code "null"}. 1504 */ valueOf(Object value)1505 public static String valueOf(Object value) { 1506 return value != null ? value.toString() : "null"; 1507 } 1508 1509 /** 1510 * Converts the specified boolean to its string representation. When the 1511 * boolean is {@code true} return {@code "true"}, otherwise return {@code 1512 * "false"}. 1513 * 1514 * @param value 1515 * the boolean. 1516 * @return the boolean converted to a string. 1517 */ valueOf(boolean value)1518 public static String valueOf(boolean value) { 1519 return value ? "true" : "false"; 1520 } 1521 1522 /** 1523 * Returns true if the {@code char}s in the given {@code StringBuffer} are the same 1524 * as those in this string. 1525 * 1526 * @throws NullPointerException 1527 * if {@code sb} is {@code null}. 1528 * @since 1.4 1529 */ contentEquals(StringBuffer sb)1530 public boolean contentEquals(StringBuffer sb) { 1531 synchronized (sb) { 1532 int size = sb.length(); 1533 if (count != size) { 1534 return false; 1535 } 1536 return regionMatches(0, new String(0, size, sb.getValue()), 0, size); 1537 } 1538 } 1539 1540 /** 1541 * Returns true if the {@code char}s in the given {@code CharSequence} are the same 1542 * as those in this string. 1543 * 1544 * @since 1.5 1545 */ contentEquals(CharSequence cs)1546 public boolean contentEquals(CharSequence cs) { 1547 if (cs == null) { 1548 throw new NullPointerException("cs == null"); 1549 } 1550 1551 int len = cs.length(); 1552 1553 if (len != count) { 1554 return false; 1555 } 1556 1557 if (len == 0 && count == 0) { 1558 return true; // since both are empty strings 1559 } 1560 1561 return regionMatches(0, cs.toString(), 0, len); 1562 } 1563 1564 /** 1565 * Tests whether this string matches the given {@code regularExpression}. This method returns 1566 * true only if the regular expression matches the <i>entire</i> input string. A common mistake is 1567 * to assume that this method behaves like {@link #contains}; if you want to match anywhere 1568 * within the input string, you need to add {@code .*} to the beginning and end of your 1569 * regular expression. See {@link Pattern#matches}. 1570 * 1571 * <p>If the same regular expression is to be used for multiple operations, it may be more 1572 * efficient to reuse a compiled {@code Pattern}. 1573 * 1574 * @throws PatternSyntaxException 1575 * if the syntax of the supplied regular expression is not 1576 * valid. 1577 * @throws NullPointerException if {@code regularExpression == null} 1578 * @since 1.4 1579 */ matches(String regularExpression)1580 public boolean matches(String regularExpression) { 1581 return Pattern.matches(regularExpression, this); 1582 } 1583 1584 /** 1585 * Replaces all matches for {@code regularExpression} within this string with the given 1586 * {@code replacement}. 1587 * See {@link Pattern} for regular expression syntax. 1588 * 1589 * <p>If the same regular expression is to be used for multiple operations, it may be more 1590 * efficient to reuse a compiled {@code Pattern}. 1591 * 1592 * @throws PatternSyntaxException 1593 * if the syntax of the supplied regular expression is not 1594 * valid. 1595 * @throws NullPointerException if {@code regularExpression == null} 1596 * @see Pattern 1597 * @since 1.4 1598 */ replaceAll(String regularExpression, String replacement)1599 public String replaceAll(String regularExpression, String replacement) { 1600 return Pattern.compile(regularExpression).matcher(this).replaceAll(replacement); 1601 } 1602 1603 /** 1604 * Replaces the first match for {@code regularExpression} within this string with the given 1605 * {@code replacement}. 1606 * See {@link Pattern} for regular expression syntax. 1607 * 1608 * <p>If the same regular expression is to be used for multiple operations, it may be more 1609 * efficient to reuse a compiled {@code Pattern}. 1610 * 1611 * @throws PatternSyntaxException 1612 * if the syntax of the supplied regular expression is not 1613 * valid. 1614 * @throws NullPointerException if {@code regularExpression == null} 1615 * @see Pattern 1616 * @since 1.4 1617 */ replaceFirst(String regularExpression, String replacement)1618 public String replaceFirst(String regularExpression, String replacement) { 1619 return Pattern.compile(regularExpression).matcher(this).replaceFirst(replacement); 1620 } 1621 1622 /** 1623 * Splits this string using the supplied {@code regularExpression}. 1624 * Equivalent to {@code split(regularExpression, 0)}. 1625 * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}. 1626 * See {@link Pattern} for regular expression syntax. 1627 * 1628 * <p>If the same regular expression is to be used for multiple operations, it may be more 1629 * efficient to reuse a compiled {@code Pattern}. 1630 * 1631 * @throws NullPointerException if {@code regularExpression == null} 1632 * @throws PatternSyntaxException 1633 * if the syntax of the supplied regular expression is not 1634 * valid. 1635 * @see Pattern 1636 * @since 1.4 1637 */ split(String regularExpression)1638 public String[] split(String regularExpression) { 1639 return split(regularExpression, 0); 1640 } 1641 1642 /** 1643 * Splits this string using the supplied {@code regularExpression}. 1644 * See {@link Pattern#split(CharSequence, int)} for an explanation of {@code limit}. 1645 * See {@link Pattern} for regular expression syntax. 1646 * 1647 * <p>If the same regular expression is to be used for multiple operations, it may be more 1648 * efficient to reuse a compiled {@code Pattern}. 1649 * 1650 * @throws NullPointerException if {@code regularExpression == null} 1651 * @throws PatternSyntaxException 1652 * if the syntax of the supplied regular expression is not 1653 * valid. 1654 * @since 1.4 1655 */ split(String regularExpression, int limit)1656 public String[] split(String regularExpression, int limit) { 1657 String[] result = java.util.regex.Splitter.fastSplit(regularExpression, this, limit); 1658 return result != null ? result : Pattern.compile(regularExpression).split(this, limit); 1659 } 1660 1661 /** 1662 * Equivalent to {@link #substring(int, int)} but needed to implement {@code CharSequence}. 1663 * 1664 * @throws IndexOutOfBoundsException 1665 * if {@code start < 0}, {@code end < 0}, {@code start > end} or 1666 * {@code end > length()}. 1667 * @see java.lang.CharSequence#subSequence(int, int) 1668 * @since 1.4 1669 */ subSequence(int start, int end)1670 public CharSequence subSequence(int start, int end) { 1671 return substring(start, end); 1672 } 1673 1674 /** 1675 * Returns the Unicode code point at the given {@code index}. 1676 * 1677 * @throws IndexOutOfBoundsException if {@code index < 0 || index >= length()} 1678 * @see Character#codePointAt(char[], int, int) 1679 * @since 1.5 1680 */ codePointAt(int index)1681 public int codePointAt(int index) { 1682 if (index < 0 || index >= count) { 1683 throw indexAndLength(index); 1684 } 1685 return Character.codePointAt(value, offset + index, offset + count); 1686 } 1687 1688 /** 1689 * Returns the Unicode code point that precedes the given {@code index}. 1690 * 1691 * @throws IndexOutOfBoundsException if {@code index < 1 || index > length()} 1692 * @see Character#codePointBefore(char[], int, int) 1693 * @since 1.5 1694 */ codePointBefore(int index)1695 public int codePointBefore(int index) { 1696 if (index < 1 || index > count) { 1697 throw indexAndLength(index); 1698 } 1699 return Character.codePointBefore(value, offset + index, offset); 1700 } 1701 1702 /** 1703 * Calculates the number of Unicode code points between {@code start} 1704 * and {@code end}. 1705 * 1706 * @param start 1707 * the inclusive beginning index of the subsequence. 1708 * @param end 1709 * the exclusive end index of the subsequence. 1710 * @return the number of Unicode code points in the subsequence. 1711 * @throws IndexOutOfBoundsException 1712 * if {@code start < 0 || end > length() || start > end} 1713 * @see Character#codePointCount(CharSequence, int, int) 1714 * @since 1.5 1715 */ codePointCount(int start, int end)1716 public int codePointCount(int start, int end) { 1717 if (start < 0 || end > count || start > end) { 1718 throw startEndAndLength(start, end); 1719 } 1720 return Character.codePointCount(value, offset + start, end - start); 1721 } 1722 1723 /** 1724 * Returns true if this string contains the {@code chars}s from the given {@code CharSequence}. 1725 * 1726 * @since 1.5 1727 */ contains(CharSequence cs)1728 public boolean contains(CharSequence cs) { 1729 if (cs == null) { 1730 throw new NullPointerException("cs == null"); 1731 } 1732 return indexOf(cs.toString()) >= 0; 1733 } 1734 1735 /** 1736 * Returns the index within this object that is offset from {@code index} by 1737 * {@code codePointOffset} code points. 1738 * 1739 * @param index 1740 * the index within this object to calculate the offset from. 1741 * @param codePointOffset 1742 * the number of code points to count. 1743 * @return the index within this object that is the offset. 1744 * @throws IndexOutOfBoundsException 1745 * if {@code index} is negative or greater than {@code length()} 1746 * or if there aren't enough code points before or after {@code 1747 * index} to match {@code codePointOffset}. 1748 * @since 1.5 1749 */ offsetByCodePoints(int index, int codePointOffset)1750 public int offsetByCodePoints(int index, int codePointOffset) { 1751 int s = index + offset; 1752 int r = Character.offsetByCodePoints(value, offset, count, s, codePointOffset); 1753 return r - offset; 1754 } 1755 1756 /** 1757 * Returns a localized formatted string, using the supplied format and arguments, 1758 * using the user's default locale. 1759 * 1760 * <p>If you're formatting a string other than for human 1761 * consumption, you should use the {@code format(Locale, String, Object...)} 1762 * overload and supply {@code Locale.US}. See 1763 * "<a href="../util/Locale.html#default_locale">Be wary of the default locale</a>". 1764 * 1765 * @param format the format string (see {@link java.util.Formatter#format}) 1766 * @param args 1767 * the list of arguments passed to the formatter. If there are 1768 * more arguments than required by {@code format}, 1769 * additional arguments are ignored. 1770 * @return the formatted string. 1771 * @throws NullPointerException if {@code format == null} 1772 * @throws java.util.IllegalFormatException 1773 * if the format is invalid. 1774 * @since 1.5 1775 */ format(String format, Object... args)1776 public static String format(String format, Object... args) { 1777 return format(Locale.getDefault(), format, args); 1778 } 1779 1780 /** 1781 * Returns a formatted string, using the supplied format and arguments, 1782 * localized to the given locale. 1783 * 1784 * @param locale 1785 * the locale to apply; {@code null} value means no localization. 1786 * @param format the format string (see {@link java.util.Formatter#format}) 1787 * @param args 1788 * the list of arguments passed to the formatter. If there are 1789 * more arguments than required by {@code format}, 1790 * additional arguments are ignored. 1791 * @return the formatted string. 1792 * @throws NullPointerException if {@code format == null} 1793 * @throws java.util.IllegalFormatException 1794 * if the format is invalid. 1795 * @since 1.5 1796 */ format(Locale locale, String format, Object... args)1797 public static String format(Locale locale, String format, Object... args) { 1798 if (format == null) { 1799 throw new NullPointerException("format == null"); 1800 } 1801 int bufferSize = format.length() + (args == null ? 0 : args.length * 10); 1802 Formatter f = new Formatter(new StringBuilder(bufferSize), locale); 1803 return f.format(format, args).toString(); 1804 } 1805 1806 /* 1807 * An implementation of a String.indexOf that is supposed to perform 1808 * substantially better than the default algorithm if the "needle" (the 1809 * subString being searched for) is a constant string. 1810 * 1811 * For example, a JIT, upon encountering a call to String.indexOf(String), 1812 * where the needle is a constant string, may compute the values cache, md2 1813 * and lastChar, and change the call to the following method. 1814 */ 1815 @FindBugsSuppressWarnings("UPM_UNCALLED_PRIVATE_METHOD") 1816 @SuppressWarnings("unused") indexOf(String haystackString, String needleString, int cache, int md2, char lastChar)1817 private static int indexOf(String haystackString, String needleString, 1818 int cache, int md2, char lastChar) { 1819 char[] haystack = haystackString.value; 1820 int haystackOffset = haystackString.offset; 1821 int haystackLength = haystackString.count; 1822 char[] needle = needleString.value; 1823 int needleOffset = needleString.offset; 1824 int needleLength = needleString.count; 1825 int needleLengthMinus1 = needleLength - 1; 1826 int haystackEnd = haystackOffset + haystackLength; 1827 outer_loop: for (int i = haystackOffset + needleLengthMinus1; i < haystackEnd;) { 1828 if (lastChar == haystack[i]) { 1829 for (int j = 0; j < needleLengthMinus1; ++j) { 1830 if (needle[j + needleOffset] != haystack[i + j 1831 - needleLengthMinus1]) { 1832 int skip = 1; 1833 if ((cache & (1 << haystack[i])) == 0) { 1834 skip += j; 1835 } 1836 i += Math.max(md2, skip); 1837 continue outer_loop; 1838 } 1839 } 1840 return i - needleLengthMinus1 - haystackOffset; 1841 } 1842 1843 if ((cache & (1 << haystack[i])) == 0) { 1844 i += needleLengthMinus1; 1845 } 1846 i++; 1847 } 1848 return -1; 1849 } 1850 } 1851