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