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