1 /* String.java -- immutable character sequences; the object of string literals 2 Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 3 Free Software Foundation, Inc. 4 5 This file is part of GNU Classpath. 6 7 GNU Classpath is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GNU Classpath is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GNU Classpath; see the file COPYING. If not, write to the 19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20 02110-1301 USA. 21 22 Linking this library statically or dynamically with other modules is 23 making a combined work based on this library. Thus, the terms and 24 conditions of the GNU General Public License cover the whole 25 combination. 26 27 As a special exception, the copyright holders of this library give you 28 permission to link this library with independent modules to produce an 29 executable, regardless of the license terms of these independent 30 modules, and to copy and distribute the resulting executable under 31 terms of your choice, provided that you also meet, for each linked 32 independent module, the terms and conditions of the license of that 33 module. An independent module is a module which is not derived from 34 or based on this library. If you modify this library, you may extend 35 this exception to your version of the library, but you are not 36 obligated to do so. If you do not wish to do so, delete this 37 exception statement from your version. */ 38 39 40 package java.lang; 41 42 import gnu.java.lang.CharData; 43 import gnu.java.lang.CPStringBuilder; 44 45 import java.io.Serializable; 46 import java.io.UnsupportedEncodingException; 47 import java.nio.ByteBuffer; 48 import java.nio.CharBuffer; 49 import java.nio.charset.CharacterCodingException; 50 import java.nio.charset.Charset; 51 import java.nio.charset.CharsetDecoder; 52 import java.nio.charset.CharsetEncoder; 53 import java.nio.charset.CodingErrorAction; 54 import java.nio.charset.IllegalCharsetNameException; 55 import java.nio.charset.UnsupportedCharsetException; 56 import java.text.Collator; 57 import java.util.Comparator; 58 import java.util.Formatter; 59 import java.util.Locale; 60 import java.util.regex.Matcher; 61 import java.util.regex.Pattern; 62 import java.util.regex.PatternSyntaxException; 63 64 /** 65 * Strings represent an immutable set of characters. All String literals 66 * are instances of this class, and two string literals with the same contents 67 * refer to the same String object. 68 * 69 * <p>This class also includes a number of methods for manipulating the 70 * contents of strings (of course, creating a new object if there are any 71 * changes, as String is immutable). Case mapping relies on Unicode 3.0.0 72 * standards, where some character sequences have a different number of 73 * characters in the uppercase version than the lower case. 74 * 75 * <p>Strings are special, in that they are the only object with an overloaded 76 * operator. When you use '+' with at least one String argument, both 77 * arguments have String conversion performed on them, and another String (not 78 * guaranteed to be unique) results. 79 * 80 * <p>String is special-cased when doing data serialization - rather than 81 * listing the fields of this class, a String object is converted to a string 82 * literal in the object stream. 83 * 84 * @author Paul N. Fisher 85 * @author Eric Blake (ebb9@email.byu.edu) 86 * @author Per Bothner (bothner@cygnus.com) 87 * @author Tom Tromey (tromey@redhat.com) 88 * @author Andrew John Hughes (gnu_andrew@member.fsf.org) 89 * @since 1.0 90 * @status updated to 1.4; but could use better data sharing via offset field 91 */ 92 public final class String 93 implements Serializable, Comparable<String>, CharSequence 94 { 95 // WARNING: String is a CORE class in the bootstrap cycle. See the comments 96 // in vm/reference/java/lang/Runtime for implications of this fact. 97 98 /** 99 * This is probably not necessary because this class is special cased already 100 * but it will avoid showing up as a discrepancy when comparing SUIDs. 101 */ 102 private static final long serialVersionUID = -6849794470754667710L; 103 104 /** 105 * Stores unicode multi-character uppercase expansion table. 106 * @see #toUpperCase(Locale) 107 * @see CharData#UPPER_EXPAND 108 */ 109 private static final char[] upperExpand 110 = zeroBasedStringValue(CharData.UPPER_EXPAND); 111 112 /** 113 * Stores unicode multi-character uppercase special casing table. 114 * @see #upperCaseExpansion(char) 115 * @see CharData#UPPER_SPECIAL 116 */ 117 private static final char[] upperSpecial 118 = zeroBasedStringValue(CharData.UPPER_SPECIAL); 119 120 /** 121 * Characters which make up the String. 122 * Package access is granted for use by StringBuffer. 123 */ 124 final char[] value; 125 126 /** 127 * Holds the number of characters in value. This number is generally 128 * the same as value.length, but can be smaller because substrings and 129 * StringBuffers can share arrays. Package visible for use by trusted code. 130 */ 131 final int count; 132 133 /** 134 * Caches the result of hashCode(). If this value is zero, the hashcode 135 * is considered uncached (even if 0 is the correct hash value). 136 */ 137 private int cachedHashCode; 138 139 /** 140 * Holds the starting position for characters in value[]. Since 141 * substring()'s are common, the use of offset allows the operation 142 * to perform in O(1). Package access is granted for use by StringBuffer. 143 */ 144 final int offset; 145 146 /** 147 * An implementation for {@link #CASE_INSENSITIVE_ORDER}. 148 * This must be {@link Serializable}. The class name is dictated by 149 * compatibility with Sun's JDK. 150 */ 151 private static final class CaseInsensitiveComparator 152 implements Comparator<String>, Serializable 153 { 154 /** 155 * Compatible with JDK 1.2. 156 */ 157 private static final long serialVersionUID = 8575799808933029326L; 158 159 /** 160 * The default private constructor generates unnecessary overhead. 161 */ CaseInsensitiveComparator()162 CaseInsensitiveComparator() {} 163 164 /** 165 * Compares to Strings, using 166 * <code>String.compareToIgnoreCase(String)</code>. 167 * 168 * @param o1 the first string 169 * @param o2 the second string 170 * @return < 0, 0, or > 0 depending on the case-insensitive 171 * comparison of the two strings. 172 * @throws NullPointerException if either argument is null 173 * @throws ClassCastException if either argument is not a String 174 * @see #compareToIgnoreCase(String) 175 */ compare(String o1, String o2)176 public int compare(String o1, String o2) 177 { 178 return o1.compareToIgnoreCase(o2); 179 } 180 } // class CaseInsensitiveComparator 181 182 /** 183 * A Comparator that uses <code>String.compareToIgnoreCase(String)</code>. 184 * This comparator is {@link Serializable}. Note that it ignores Locale, 185 * for that, you want a Collator. 186 * 187 * @see Collator#compare(String, String) 188 * @since 1.2 189 */ 190 public static final Comparator<String> CASE_INSENSITIVE_ORDER 191 = new CaseInsensitiveComparator(); 192 193 /** 194 * Creates an empty String (length 0). Unless you really need a new object, 195 * consider using <code>""</code> instead. 196 */ String()197 public String() 198 { 199 value = "".value; 200 offset = 0; 201 count = 0; 202 } 203 204 /** 205 * Copies the contents of a String to a new String. Since Strings are 206 * immutable, only a shallow copy is performed. 207 * 208 * @param str String to copy 209 * @throws NullPointerException if value is null 210 */ String(String str)211 public String(String str) 212 { 213 value = str.value; 214 offset = str.offset; 215 count = str.count; 216 cachedHashCode = str.cachedHashCode; 217 } 218 219 /** 220 * Creates a new String using the character sequence of the char array. 221 * Subsequent changes to data do not affect the String. 222 * 223 * @param data char array to copy 224 * @throws NullPointerException if data is null 225 */ String(char[] data)226 public String(char[] data) 227 { 228 this(data, 0, data.length, false); 229 } 230 231 /** 232 * Creates a new String using the character sequence of a subarray of 233 * characters. The string starts at offset, and copies count chars. 234 * Subsequent changes to data do not affect the String. 235 * 236 * @param data char array to copy 237 * @param offset position (base 0) to start copying out of data 238 * @param count the number of characters from data to copy 239 * @throws NullPointerException if data is null 240 * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 241 * || offset + count < 0 (overflow) 242 * || offset + count > data.length) 243 * (while unspecified, this is a StringIndexOutOfBoundsException) 244 */ String(char[] data, int offset, int count)245 public String(char[] data, int offset, int count) 246 { 247 this(data, offset, count, false); 248 } 249 250 /** 251 * Creates a new String using an 8-bit array of integer values, starting at 252 * an offset, and copying up to the count. Each character c, using 253 * corresponding byte b, is created in the new String as if by performing: 254 * 255 * <pre> 256 * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) 257 * </pre> 258 * 259 * @param ascii array of integer values 260 * @param hibyte top byte of each Unicode character 261 * @param offset position (base 0) to start copying out of ascii 262 * @param count the number of characters from ascii to copy 263 * @throws NullPointerException if ascii is null 264 * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 265 * || offset + count < 0 (overflow) 266 * || offset + count > ascii.length) 267 * (while unspecified, this is a StringIndexOutOfBoundsException) 268 * @see #String(byte[]) 269 * @see #String(byte[], String) 270 * @see #String(byte[], int, int) 271 * @see #String(byte[], int, int, String) 272 * @deprecated use {@link #String(byte[], int, int, String)} to perform 273 * correct encoding 274 */ String(byte[] ascii, int hibyte, int offset, int count)275 public String(byte[] ascii, int hibyte, int offset, int count) 276 { 277 if (offset < 0) 278 throw new StringIndexOutOfBoundsException("offset: " + offset); 279 if (count < 0) 280 throw new StringIndexOutOfBoundsException("count: " + count); 281 // equivalent to: offset + count < 0 || offset + count > ascii.length 282 if (ascii.length - offset < count) 283 throw new StringIndexOutOfBoundsException("offset + count: " 284 + (offset + count)); 285 value = new char[count]; 286 this.offset = 0; 287 this.count = count; 288 hibyte <<= 8; 289 offset += count; 290 while (--count >= 0) 291 value[count] = (char) (hibyte | (ascii[--offset] & 0xff)); 292 } 293 294 /** 295 * Creates a new String using an 8-bit array of integer values. Each 296 * character c, using corresponding byte b, is created in the new String 297 * as if by performing: 298 * 299 * <pre> 300 * c = (char) (((hibyte & 0xff) << 8) | (b & 0xff)) 301 * </pre> 302 * 303 * @param ascii array of integer values 304 * @param hibyte top byte of each Unicode character 305 * @throws NullPointerException if ascii is null 306 * @see #String(byte[]) 307 * @see #String(byte[], String) 308 * @see #String(byte[], int, int) 309 * @see #String(byte[], int, int, String) 310 * @see #String(byte[], int, int, int) 311 * @deprecated use {@link #String(byte[], String)} to perform 312 * correct encoding 313 */ String(byte[] ascii, int hibyte)314 public String(byte[] ascii, int hibyte) 315 { 316 this(ascii, hibyte, 0, ascii.length); 317 } 318 319 /** 320 * Creates a new String using the portion of the byte array starting at the 321 * offset and ending at offset + count. Uses the specified encoding type 322 * to decode the byte array, so the resulting string may be longer or 323 * shorter than the byte array. For more decoding control, use 324 * {@link java.nio.charset.CharsetDecoder}, and for valid character sets, 325 * see {@link java.nio.charset.Charset}. The behavior is not specified if 326 * the decoder encounters invalid characters; this implementation throws 327 * an Error. 328 * 329 * @param data byte array to copy 330 * @param offset the offset to start at 331 * @param count the number of bytes in the array to use 332 * @param encoding the name of the encoding to use 333 * @throws NullPointerException if data or encoding is null 334 * @throws IndexOutOfBoundsException if offset or count is incorrect 335 * (while unspecified, this is a StringIndexOutOfBoundsException) 336 * @throws UnsupportedEncodingException if encoding is not found 337 * @throws Error if the decoding fails 338 * @since 1.1 339 */ String(byte[] data, int offset, int count, final String encoding)340 public String(byte[] data, int offset, int count, final String encoding) 341 throws UnsupportedEncodingException 342 { 343 this(data, offset, count, stringToCharset(encoding)); 344 } 345 346 /** 347 * Wrapper method to convert exceptions resulting from 348 * the selection of a {@link java.nio.charset.Charset} based on 349 * a String. 350 * 351 * @throws UnsupportedEncodingException if encoding is not found 352 */ stringToCharset(final String encoding)353 private static final Charset stringToCharset(final String encoding) 354 throws UnsupportedEncodingException 355 { 356 try 357 { 358 return Charset.forName(encoding); 359 } 360 catch(IllegalCharsetNameException e) 361 { 362 throw new UnsupportedEncodingException("Encoding: "+encoding+ 363 " not found."); 364 } 365 catch(UnsupportedCharsetException e) 366 { 367 throw new UnsupportedEncodingException("Encoding: "+encoding+ 368 " not found."); 369 } 370 } 371 372 /** 373 * Creates a new String using the portion of the byte array starting at the 374 * offset and ending at offset + count. Uses the specified encoding type 375 * to decode the byte array, so the resulting string may be longer or 376 * shorter than the byte array. For more decoding control, use 377 * {@link java.nio.charset.CharsetDecoder}, and for valid character sets, 378 * see {@link java.nio.charset.Charset}. Malformed input and unmappable 379 * character sequences are replaced with the default replacement string 380 * provided by the {@link java.nio.charset.Charset}. 381 * 382 * @param data byte array to copy 383 * @param offset the offset to start at 384 * @param count the number of bytes in the array to use 385 * @param encoding the encoding to use 386 * @throws NullPointerException if data or encoding is null 387 * @throws IndexOutOfBoundsException if offset or count is incorrect 388 * (while unspecified, this is a StringIndexOutOfBoundsException) 389 * @since 1.6 390 */ String(byte[] data, int offset, int count, Charset encoding)391 public String(byte[] data, int offset, int count, Charset encoding) 392 { 393 if (offset < 0) 394 throw new StringIndexOutOfBoundsException("offset: " + offset); 395 if (count < 0) 396 throw new StringIndexOutOfBoundsException("count: " + count); 397 // equivalent to: offset + count < 0 || offset + count > data.length 398 if (data.length - offset < count) 399 throw new StringIndexOutOfBoundsException("offset + count: " 400 + (offset + count)); 401 try 402 { 403 CharsetDecoder csd = encoding.newDecoder(); 404 csd.onMalformedInput(CodingErrorAction.REPLACE); 405 csd.onUnmappableCharacter(CodingErrorAction.REPLACE); 406 CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count)); 407 if(cbuf.hasArray()) 408 { 409 value = cbuf.array(); 410 this.offset = cbuf.position(); 411 this.count = cbuf.remaining(); 412 } else { 413 // Doubt this will happen. But just in case. 414 value = new char[cbuf.remaining()]; 415 cbuf.get(value); 416 this.offset = 0; 417 this.count = value.length; 418 } 419 } 420 catch(CharacterCodingException e) 421 { 422 // This shouldn't ever happen. 423 throw (InternalError) new InternalError().initCause(e); 424 } 425 } 426 427 /** 428 * Creates a new String using the byte array. Uses the specified encoding 429 * type to decode the byte array, so the resulting string may be longer or 430 * shorter than the byte array. For more decoding control, use 431 * {@link java.nio.charset.CharsetDecoder}, and for valid character sets, 432 * see {@link java.nio.charset.Charset}. The behavior is not specified if 433 * the decoder encounters invalid characters; this implementation throws 434 * an Error. 435 * 436 * @param data byte array to copy 437 * @param encoding the name of the encoding to use 438 * @throws NullPointerException if data or encoding is null 439 * @throws UnsupportedEncodingException if encoding is not found 440 * @throws Error if the decoding fails 441 * @see #String(byte[], int, int, String) 442 * @since 1.1 443 */ String(byte[] data, String encoding)444 public String(byte[] data, String encoding) 445 throws UnsupportedEncodingException 446 { 447 this(data, 0, data.length, encoding); 448 } 449 450 /** 451 * Creates a new String using the byte array. Uses the specified encoding 452 * type to decode the byte array, so the resulting string may be longer or 453 * shorter than the byte array. For more decoding control, use 454 * {@link java.nio.charset.CharsetDecoder}, and for valid character sets, 455 * see {@link java.nio.charset.Charset}. Malformed input and unmappable 456 * character sequences are replaced with the default replacement string 457 * provided by the {@link java.nio.charset.Charset}. 458 * 459 * @param data byte array to copy 460 * @param encoding the name of the encoding to use 461 * @throws NullPointerException if data or encoding is null 462 * @see #String(byte[], int, int, java.nio.Charset) 463 * @since 1.6 464 */ String(byte[] data, Charset encoding)465 public String(byte[] data, Charset encoding) 466 { 467 this(data, 0, data.length, encoding); 468 } 469 470 /** 471 * Creates a new String using the portion of the byte array starting at the 472 * offset and ending at offset + count. Uses the encoding of the platform's 473 * default charset, so the resulting string may be longer or shorter than 474 * the byte array. For more decoding control, use 475 * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified 476 * if the decoder encounters invalid characters; this implementation throws 477 * an Error. 478 * 479 * @param data byte array to copy 480 * @param offset the offset to start at 481 * @param count the number of bytes in the array to use 482 * @throws NullPointerException if data is null 483 * @throws IndexOutOfBoundsException if offset or count is incorrect 484 * @throws Error if the decoding fails 485 * @see #String(byte[], int, int, String) 486 * @since 1.1 487 */ String(byte[] data, int offset, int count)488 public String(byte[] data, int offset, int count) 489 { 490 if (offset < 0) 491 throw new StringIndexOutOfBoundsException("offset: " + offset); 492 if (count < 0) 493 throw new StringIndexOutOfBoundsException("count: " + count); 494 // equivalent to: offset + count < 0 || offset + count > data.length 495 if (data.length - offset < count) 496 throw new StringIndexOutOfBoundsException("offset + count: " 497 + (offset + count)); 498 int o, c; 499 char[] v; 500 String encoding; 501 try 502 { 503 encoding = System.getProperty("file.encoding"); 504 CharsetDecoder csd = Charset.forName(encoding).newDecoder(); 505 csd.onMalformedInput(CodingErrorAction.REPLACE); 506 csd.onUnmappableCharacter(CodingErrorAction.REPLACE); 507 CharBuffer cbuf = csd.decode(ByteBuffer.wrap(data, offset, count)); 508 if(cbuf.hasArray()) 509 { 510 v = cbuf.array(); 511 o = cbuf.position(); 512 c = cbuf.remaining(); 513 } else { 514 // Doubt this will happen. But just in case. 515 v = new char[cbuf.remaining()]; 516 cbuf.get(v); 517 o = 0; 518 c = v.length; 519 } 520 } catch(Exception ex){ 521 // If anything goes wrong (System property not set, 522 // NIO provider not available, etc) 523 // Default to the 'safe' encoding ISO8859_1 524 v = new char[count]; 525 o = 0; 526 c = count; 527 for (int i=0;i<count;i++) 528 v[i] = (char)data[offset+i]; 529 } 530 this.value = v; 531 this.offset = o; 532 this.count = c; 533 } 534 535 /** 536 * Creates a new String using the byte array. Uses the encoding of the 537 * platform's default charset, so the resulting string may be longer or 538 * shorter than the byte array. For more decoding control, use 539 * {@link java.nio.charset.CharsetDecoder}. The behavior is not specified 540 * if the decoder encounters invalid characters; this implementation throws 541 * an Error. 542 * 543 * @param data byte array to copy 544 * @throws NullPointerException if data is null 545 * @throws Error if the decoding fails 546 * @see #String(byte[], int, int) 547 * @see #String(byte[], int, int, String) 548 * @since 1.1 549 */ String(byte[] data)550 public String(byte[] data) 551 { 552 this(data, 0, data.length); 553 } 554 555 /** 556 * Creates a new String using the character sequence represented by 557 * the StringBuffer. Subsequent changes to buf do not affect the String. 558 * 559 * @param buffer StringBuffer to copy 560 * @throws NullPointerException if buffer is null 561 */ String(StringBuffer buffer)562 public String(StringBuffer buffer) 563 { 564 synchronized (buffer) 565 { 566 offset = 0; 567 count = buffer.count; 568 // Share unless buffer is 3/4 empty. 569 if ((count << 2) < buffer.value.length) 570 { 571 value = new char[count]; 572 VMSystem.arraycopy(buffer.value, 0, value, 0, count); 573 } 574 else 575 { 576 buffer.shared = true; 577 value = buffer.value; 578 } 579 } 580 } 581 582 /** 583 * Creates a new String using the character sequence represented by 584 * the StringBuilder. Subsequent changes to buf do not affect the String. 585 * 586 * @param buffer StringBuilder to copy 587 * @throws NullPointerException if buffer is null 588 */ String(StringBuilder buffer)589 public String(StringBuilder buffer) 590 { 591 this(buffer.value, 0, buffer.count); 592 } 593 594 /** 595 * Special constructor which can share an array when safe to do so. 596 * 597 * @param data the characters to copy 598 * @param offset the location to start from 599 * @param count the number of characters to use 600 * @param dont_copy true if the array is trusted, and need not be copied 601 * @throws NullPointerException if chars is null 602 * @throws StringIndexOutOfBoundsException if bounds check fails 603 */ String(char[] data, int offset, int count, boolean dont_copy)604 String(char[] data, int offset, int count, boolean dont_copy) 605 { 606 if (offset < 0) 607 throw new StringIndexOutOfBoundsException("offset: " + offset); 608 if (count < 0) 609 throw new StringIndexOutOfBoundsException("count: " + count); 610 // equivalent to: offset + count < 0 || offset + count > data.length 611 if (data.length - offset < count) 612 throw new StringIndexOutOfBoundsException("offset + count: " 613 + (offset + count)); 614 if (dont_copy) 615 { 616 value = data; 617 this.offset = offset; 618 } 619 else 620 { 621 value = new char[count]; 622 VMSystem.arraycopy(data, offset, value, 0, count); 623 this.offset = 0; 624 } 625 this.count = count; 626 } 627 628 /** 629 * Creates a new String containing the characters represented in the 630 * given subarray of Unicode code points. 631 * @param codePoints the entire array of code points 632 * @param offset the start of the subarray 633 * @param count the length of the subarray 634 * 635 * @throws IllegalArgumentException if an invalid code point is found 636 * in the codePoints array 637 * @throws IndexOutOfBoundsException if offset is negative or offset + count 638 * is greater than the length of the array. 639 */ String(int[] codePoints, int offset, int count)640 public String(int[] codePoints, int offset, int count) 641 { 642 // FIXME: This implementation appears to give correct internal 643 // representation of the String because: 644 // - length() is correct 645 // - getting a char[] from toCharArray() and testing 646 // Character.codePointAt() on all the characters in that array gives 647 // the appropriate results 648 // however printing the String gives incorrect results. This may be 649 // due to printing method errors (such as incorrectly looping through 650 // the String one char at a time rather than one "character" at a time. 651 652 if (offset < 0) 653 throw new IndexOutOfBoundsException(); 654 int end = offset + count; 655 int pos = 0; 656 // This creates a char array that is long enough for all of the code 657 // points to represent supplementary characters. This is more than likely 658 // a waste of storage, so we use it only temporarily and then copy the 659 // used portion into the value array. 660 char[] temp = new char[2 * codePoints.length]; 661 for (int i = offset; i < end; i++) 662 { 663 pos += Character.toChars(codePoints[i], temp, pos); 664 } 665 this.count = pos; 666 this.value = new char[pos]; 667 System.arraycopy(temp, 0, value, 0, pos); 668 this.offset = 0; 669 } 670 671 /** 672 * Returns the number of characters contained in this String. 673 * 674 * @return the length of this String 675 */ length()676 public int length() 677 { 678 return count; 679 } 680 681 /** 682 * Returns the character located at the specified index within this String. 683 * 684 * @param index position of character to return (base 0) 685 * @return character located at position index 686 * @throws IndexOutOfBoundsException if index < 0 || index >= length() 687 * (while unspecified, this is a StringIndexOutOfBoundsException) 688 */ charAt(int index)689 public char charAt(int index) 690 { 691 if (index < 0 || index >= count) 692 throw new StringIndexOutOfBoundsException(index); 693 return value[offset + index]; 694 } 695 696 /** 697 * Get the code point at the specified index. This is like #charAt(int), 698 * but if the character is the start of a surrogate pair, and the 699 * following character completes the pair, then the corresponding 700 * supplementary code point is returned. 701 * @param index the index of the codepoint to get, starting at 0 702 * @return the codepoint at the specified index 703 * @throws IndexOutOfBoundsException if index is negative or >= length() 704 * @since 1.5 705 */ codePointAt(int index)706 public synchronized int codePointAt(int index) 707 { 708 if (index < 0 || index >= count) 709 throw new StringIndexOutOfBoundsException(index); 710 // Use the CharSequence overload as we get better range checking 711 // this way. 712 return Character.codePointAt(this, index); 713 } 714 715 /** 716 * Get the code point before the specified index. This is like 717 * #codePointAt(int), but checks the characters at <code>index-1</code> and 718 * <code>index-2</code> to see if they form a supplementary code point. 719 * @param index the index just past the codepoint to get, starting at 0 720 * @return the codepoint at the specified index 721 * @throws IndexOutOfBoundsException if index is less than 1 or > length() 722 * (while unspecified, this is a StringIndexOutOfBoundsException) 723 * @since 1.5 724 */ codePointBefore(int index)725 public synchronized int codePointBefore(int index) 726 { 727 if (index < 1 || index > count) 728 throw new StringIndexOutOfBoundsException(index); 729 // Use the CharSequence overload as we get better range checking 730 // this way. 731 return Character.codePointBefore(this, index); 732 } 733 734 /** 735 * Copies characters from this String starting at a specified start index, 736 * ending at a specified stop index, to a character array starting at 737 * a specified destination begin index. 738 * 739 * @param srcBegin index to begin copying characters from this String 740 * @param srcEnd index after the last character to be copied from this String 741 * @param dst character array which this String is copied into 742 * @param dstBegin index to start writing characters into dst 743 * @throws NullPointerException if dst is null 744 * @throws IndexOutOfBoundsException if any indices are out of bounds 745 * (while unspecified, source problems cause a 746 * StringIndexOutOfBoundsException, and dst problems cause an 747 * ArrayIndexOutOfBoundsException) 748 */ getChars(int srcBegin, int srcEnd, char dst[], int dstBegin)749 public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) 750 { 751 if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count) 752 throw new StringIndexOutOfBoundsException(); 753 VMSystem.arraycopy(value, srcBegin + offset, 754 dst, dstBegin, srcEnd - srcBegin); 755 } 756 757 /** 758 * Copies the low byte of each character from this String starting at a 759 * specified start index, ending at a specified stop index, to a byte array 760 * starting at a specified destination begin index. 761 * 762 * @param srcBegin index to being copying characters from this String 763 * @param srcEnd index after the last character to be copied from this String 764 * @param dst byte array which each low byte of this String is copied into 765 * @param dstBegin index to start writing characters into dst 766 * @throws NullPointerException if dst is null and copy length is non-zero 767 * @throws IndexOutOfBoundsException if any indices are out of bounds 768 * (while unspecified, source problems cause a 769 * StringIndexOutOfBoundsException, and dst problems cause an 770 * ArrayIndexOutOfBoundsException) 771 * @see #getBytes() 772 * @see #getBytes(String) 773 * @deprecated use {@link #getBytes()}, which uses a char to byte encoder 774 */ getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin)775 public void getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) 776 { 777 if (srcBegin < 0 || srcBegin > srcEnd || srcEnd > count) 778 throw new StringIndexOutOfBoundsException(); 779 int i = srcEnd - srcBegin; 780 srcBegin += offset; 781 while (--i >= 0) 782 dst[dstBegin++] = (byte) value[srcBegin++]; 783 } 784 785 /** 786 * Converts the Unicode characters in this String to a byte array. Uses the 787 * specified encoding method, so the result may be longer or shorter than 788 * the String. For more encoding control, use 789 * {@link java.nio.charset.CharsetEncoder}, and for valid character sets, 790 * see {@link java.nio.charset.Charset}. Unsupported characters get 791 * replaced by an encoding specific byte. 792 * 793 * @param enc encoding name 794 * @return the resulting byte array 795 * @throws NullPointerException if enc is null 796 * @throws UnsupportedEncodingException if encoding is not supported 797 * @since 1.1 798 */ getBytes(final String enc)799 public byte[] getBytes(final String enc) 800 throws UnsupportedEncodingException 801 { 802 return getBytes(stringToCharset(enc)); 803 } 804 805 /** 806 * Converts the Unicode characters in this String to a byte array. Uses the 807 * specified encoding method, so the result may be longer or shorter than 808 * the String. For more encoding control, use 809 * {@link java.nio.charset.CharsetEncoder}, and for valid character sets, 810 * see {@link java.nio.charset.Charset}. Unsupported characters get 811 * replaced by the {@link java.nio.charset.Charset}'s default replacement. 812 * 813 * @param enc encoding name 814 * @return the resulting byte array 815 * @throws NullPointerException if enc is null 816 * @since 1.6 817 */ getBytes(Charset enc)818 public byte[] getBytes(Charset enc) 819 { 820 try 821 { 822 CharsetEncoder cse = enc.newEncoder(); 823 cse.onMalformedInput(CodingErrorAction.REPLACE); 824 cse.onUnmappableCharacter(CodingErrorAction.REPLACE); 825 ByteBuffer bbuf = cse.encode(CharBuffer.wrap(value, offset, count)); 826 if(bbuf.hasArray()) 827 return bbuf.array(); 828 829 // Doubt this will happen. But just in case. 830 byte[] bytes = new byte[bbuf.remaining()]; 831 bbuf.get(bytes); 832 return bytes; 833 } 834 catch(CharacterCodingException e) 835 { 836 // This shouldn't ever happen. 837 throw (InternalError) new InternalError().initCause(e); 838 } 839 } 840 841 /** 842 * Converts the Unicode characters in this String to a byte array. Uses the 843 * encoding of the platform's default charset, so the result may be longer 844 * or shorter than the String. For more encoding control, use 845 * {@link java.nio.charset.CharsetEncoder}. Unsupported characters get 846 * replaced by an encoding specific byte. 847 * 848 * @return the resulting byte array, or null on a problem 849 * @since 1.1 850 */ getBytes()851 public byte[] getBytes() 852 { 853 try 854 { 855 return getBytes(System.getProperty("file.encoding")); 856 } catch(Exception e) { 857 // XXX - Throw an error here? 858 // For now, default to the 'safe' encoding. 859 byte[] bytes = new byte[count]; 860 for(int i=0;i<count;i++) 861 bytes[i] = (byte)((value[offset+i] <= 0xFF)? 862 value[offset+i]:'?'); 863 return bytes; 864 } 865 } 866 867 /** 868 * Predicate which compares anObject to this. This is true only for Strings 869 * with the same character sequence. 870 * 871 * @param anObject the object to compare 872 * @return true if anObject is semantically equal to this 873 * @see #compareTo(String) 874 * @see #equalsIgnoreCase(String) 875 */ equals(Object anObject)876 public boolean equals(Object anObject) 877 { 878 if (! (anObject instanceof String)) 879 return false; 880 String str2 = (String) anObject; 881 if (count != str2.count) 882 return false; 883 if (value == str2.value && offset == str2.offset) 884 return true; 885 int i = count; 886 int x = offset; 887 int y = str2.offset; 888 while (--i >= 0) 889 if (value[x++] != str2.value[y++]) 890 return false; 891 return true; 892 } 893 894 /** 895 * Compares the given StringBuffer to this String. This is true if the 896 * StringBuffer has the same content as this String at this moment. 897 * 898 * @param buffer the StringBuffer to compare to 899 * @return true if StringBuffer has the same character sequence 900 * @throws NullPointerException if the given StringBuffer is null 901 * @since 1.4 902 */ contentEquals(StringBuffer buffer)903 public boolean contentEquals(StringBuffer buffer) 904 { 905 synchronized (buffer) 906 { 907 if (count != buffer.count) 908 return false; 909 if (value == buffer.value) 910 return true; // Possible if shared. 911 int i = count; 912 int x = offset + count; 913 while (--i >= 0) 914 if (value[--x] != buffer.value[i]) 915 return false; 916 return true; 917 } 918 } 919 920 /** 921 * Compares the given CharSequence to this String. This is true if 922 * the CharSequence has the same content as this String at this 923 * moment. 924 * 925 * @param seq the CharSequence to compare to 926 * @return true if CharSequence has the same character sequence 927 * @throws NullPointerException if the given CharSequence is null 928 * @since 1.5 929 */ contentEquals(CharSequence seq)930 public boolean contentEquals(CharSequence seq) 931 { 932 if (seq.length() != count) 933 return false; 934 for (int i = 0; i < count; ++i) 935 if (value[offset + i] != seq.charAt(i)) 936 return false; 937 return true; 938 } 939 940 /** 941 * Compares a String to this String, ignoring case. This does not handle 942 * multi-character capitalization exceptions; instead the comparison is 943 * made on a character-by-character basis, and is true if:<br><ul> 944 * <li><code>c1 == c2</code></li> 945 * <li><code>Character.toUpperCase(c1) 946 * == Character.toUpperCase(c2)</code></li> 947 * <li><code>Character.toLowerCase(c1) 948 * == Character.toLowerCase(c2)</code></li> 949 * </ul> 950 * 951 * @param anotherString String to compare to this String 952 * @return true if anotherString is equal, ignoring case 953 * @see #equals(Object) 954 * @see Character#toUpperCase(char) 955 * @see Character#toLowerCase(char) 956 */ equalsIgnoreCase(String anotherString)957 public boolean equalsIgnoreCase(String anotherString) 958 { 959 if (anotherString == null || count != anotherString.count) 960 return false; 961 int i = count; 962 int x = offset; 963 int y = anotherString.offset; 964 while (--i >= 0) 965 { 966 char c1 = value[x++]; 967 char c2 = anotherString.value[y++]; 968 // Note that checking c1 != c2 is redundant, but avoids method calls. 969 if (c1 != c2 970 && Character.toUpperCase(c1) != Character.toUpperCase(c2) 971 && Character.toLowerCase(c1) != Character.toLowerCase(c2)) 972 return false; 973 } 974 return true; 975 } 976 977 /** 978 * Compares this String and another String (case sensitive, 979 * lexicographically). The result is less than 0 if this string sorts 980 * before the other, 0 if they are equal, and greater than 0 otherwise. 981 * After any common starting sequence is skipped, the result is 982 * <code>this.charAt(k) - anotherString.charAt(k)</code> if both strings 983 * have characters remaining, or 984 * <code>this.length() - anotherString.length()</code> if one string is 985 * a subsequence of the other. 986 * 987 * @param anotherString the String to compare against 988 * @return the comparison 989 * @throws NullPointerException if anotherString is null 990 */ compareTo(String anotherString)991 public int compareTo(String anotherString) 992 { 993 int i = Math.min(count, anotherString.count); 994 int x = offset; 995 int y = anotherString.offset; 996 while (--i >= 0) 997 { 998 int result = value[x++] - anotherString.value[y++]; 999 if (result != 0) 1000 return result; 1001 } 1002 return count - anotherString.count; 1003 } 1004 1005 /** 1006 * Compares this String and another String (case insensitive). This 1007 * comparison is <em>similar</em> to equalsIgnoreCase, in that it ignores 1008 * locale and multi-characater capitalization, and compares characters 1009 * after performing 1010 * <code>Character.toLowerCase(Character.toUpperCase(c))</code> on each 1011 * character of the string. This is unsatisfactory for locale-based 1012 * comparison, in which case you should use {@link java.text.Collator}. 1013 * 1014 * @param str the string to compare against 1015 * @return the comparison 1016 * @see Collator#compare(String, String) 1017 * @since 1.2 1018 */ compareToIgnoreCase(String str)1019 public int compareToIgnoreCase(String str) 1020 { 1021 int i = Math.min(count, str.count); 1022 int x = offset; 1023 int y = str.offset; 1024 while (--i >= 0) 1025 { 1026 int result = Character.toLowerCase(Character.toUpperCase(value[x++])) 1027 - Character.toLowerCase(Character.toUpperCase(str.value[y++])); 1028 if (result != 0) 1029 return result; 1030 } 1031 return count - str.count; 1032 } 1033 1034 /** 1035 * Predicate which determines if this String matches another String 1036 * starting at a specified offset for each String and continuing 1037 * for a specified length. Indices out of bounds are harmless, and give 1038 * a false result. 1039 * 1040 * @param toffset index to start comparison at for this String 1041 * @param other String to compare region to this String 1042 * @param ooffset index to start comparison at for other 1043 * @param len number of characters to compare 1044 * @return true if regions match (case sensitive) 1045 * @throws NullPointerException if other is null 1046 */ regionMatches(int toffset, String other, int ooffset, int len)1047 public boolean regionMatches(int toffset, String other, int ooffset, int len) 1048 { 1049 return regionMatches(false, toffset, other, ooffset, len); 1050 } 1051 1052 /** 1053 * Predicate which determines if this String matches another String 1054 * starting at a specified offset for each String and continuing 1055 * for a specified length, optionally ignoring case. Indices out of bounds 1056 * are harmless, and give a false result. Case comparisons are based on 1057 * <code>Character.toLowerCase()</code> and 1058 * <code>Character.toUpperCase()</code>, not on multi-character 1059 * capitalization expansions. 1060 * 1061 * @param ignoreCase true if case should be ignored in comparision 1062 * @param toffset index to start comparison at for this String 1063 * @param other String to compare region to this String 1064 * @param ooffset index to start comparison at for other 1065 * @param len number of characters to compare 1066 * @return true if regions match, false otherwise 1067 * @throws NullPointerException if other is null 1068 */ regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len)1069 public boolean regionMatches(boolean ignoreCase, int toffset, 1070 String other, int ooffset, int len) 1071 { 1072 if (toffset < 0 || ooffset < 0 || toffset + len > count 1073 || ooffset + len > other.count) 1074 return false; 1075 toffset += offset; 1076 ooffset += other.offset; 1077 while (--len >= 0) 1078 { 1079 char c1 = value[toffset++]; 1080 char c2 = other.value[ooffset++]; 1081 // Note that checking c1 != c2 is redundant when ignoreCase is true, 1082 // but it avoids method calls. 1083 if (c1 != c2 1084 && (! ignoreCase 1085 || (Character.toLowerCase(c1) != Character.toLowerCase(c2) 1086 && (Character.toUpperCase(c1) 1087 != Character.toUpperCase(c2))))) 1088 return false; 1089 } 1090 return true; 1091 } 1092 1093 /** 1094 * Predicate which determines if this String contains the given prefix, 1095 * beginning comparison at toffset. The result is false if toffset is 1096 * negative or greater than this.length(), otherwise it is the same as 1097 * <code>this.substring(toffset).startsWith(prefix)</code>. 1098 * 1099 * @param prefix String to compare 1100 * @param toffset offset for this String where comparison starts 1101 * @return true if this String starts with prefix 1102 * @throws NullPointerException if prefix is null 1103 * @see #regionMatches(boolean, int, String, int, int) 1104 */ startsWith(String prefix, int toffset)1105 public boolean startsWith(String prefix, int toffset) 1106 { 1107 return regionMatches(false, toffset, prefix, 0, prefix.count); 1108 } 1109 1110 /** 1111 * Predicate which determines if this String starts with a given prefix. 1112 * If the prefix is an empty String, true is returned. 1113 * 1114 * @param prefix String to compare 1115 * @return true if this String starts with the prefix 1116 * @throws NullPointerException if prefix is null 1117 * @see #startsWith(String, int) 1118 */ startsWith(String prefix)1119 public boolean startsWith(String prefix) 1120 { 1121 return regionMatches(false, 0, prefix, 0, prefix.count); 1122 } 1123 1124 /** 1125 * Predicate which determines if this String ends with a given suffix. 1126 * If the suffix is an empty String, true is returned. 1127 * 1128 * @param suffix String to compare 1129 * @return true if this String ends with the suffix 1130 * @throws NullPointerException if suffix is null 1131 * @see #regionMatches(boolean, int, String, int, int) 1132 */ endsWith(String suffix)1133 public boolean endsWith(String suffix) 1134 { 1135 return regionMatches(false, count - suffix.count, suffix, 0, suffix.count); 1136 } 1137 1138 /** 1139 * Computes the hashcode for this String. This is done with int arithmetic, 1140 * where ** represents exponentiation, by this formula:<br> 1141 * <code>s[0]*31**(n-1) + s[1]*31**(n-2) + ... + s[n-1]</code>. 1142 * 1143 * @return hashcode value of this String 1144 */ hashCode()1145 public int hashCode() 1146 { 1147 if (cachedHashCode != 0) 1148 return cachedHashCode; 1149 1150 // Compute the hash code using a local variable to be reentrant. 1151 int hashCode = 0; 1152 int limit = count + offset; 1153 for (int i = offset; i < limit; i++) 1154 hashCode = hashCode * 31 + value[i]; 1155 return cachedHashCode = hashCode; 1156 } 1157 1158 /** 1159 * Finds the first instance of a character in this String. 1160 * 1161 * @param ch character to find 1162 * @return location (base 0) of the character, or -1 if not found 1163 */ indexOf(int ch)1164 public int indexOf(int ch) 1165 { 1166 return indexOf(ch, 0); 1167 } 1168 1169 /** 1170 * Finds the first instance of a character in this String, starting at 1171 * a given index. If starting index is less than 0, the search 1172 * starts at the beginning of this String. If the starting index 1173 * is greater than the length of this String, -1 is returned. 1174 * 1175 * @param ch character to find 1176 * @param fromIndex index to start the search 1177 * @return location (base 0) of the character, or -1 if not found 1178 */ indexOf(int ch, int fromIndex)1179 public int indexOf(int ch, int fromIndex) 1180 { 1181 if ((char) ch != ch) 1182 return -1; 1183 if (fromIndex < 0) 1184 fromIndex = 0; 1185 int i = fromIndex + offset; 1186 for ( ; fromIndex < count; fromIndex++) 1187 if (value[i++] == ch) 1188 return fromIndex; 1189 return -1; 1190 } 1191 1192 /** 1193 * Finds the last instance of a character in this String. 1194 * 1195 * @param ch character to find 1196 * @return location (base 0) of the character, or -1 if not found 1197 */ lastIndexOf(int ch)1198 public int lastIndexOf(int ch) 1199 { 1200 return lastIndexOf(ch, count - 1); 1201 } 1202 1203 /** 1204 * Finds the last instance of a character in this String, starting at 1205 * a given index. If starting index is greater than the maximum valid 1206 * index, then the search begins at the end of this String. If the 1207 * starting index is less than zero, -1 is returned. 1208 * 1209 * @param ch character to find 1210 * @param fromIndex index to start the search 1211 * @return location (base 0) of the character, or -1 if not found 1212 */ lastIndexOf(int ch, int fromIndex)1213 public int lastIndexOf(int ch, int fromIndex) 1214 { 1215 if ((char) ch != ch) 1216 return -1; 1217 if (fromIndex >= count) 1218 fromIndex = count - 1; 1219 int i = fromIndex + offset; 1220 for ( ; fromIndex >= 0; fromIndex--) 1221 if (value[i--] == ch) 1222 return fromIndex; 1223 return -1; 1224 } 1225 1226 /** 1227 * Finds the first instance of a String in this String. 1228 * 1229 * @param str String to find 1230 * @return location (base 0) of the String, or -1 if not found 1231 * @throws NullPointerException if str is null 1232 */ indexOf(String str)1233 public int indexOf(String str) 1234 { 1235 return indexOf(str, 0); 1236 } 1237 1238 /** 1239 * Finds the first instance of a String in this String, starting at 1240 * a given index. If starting index is less than 0, the search 1241 * starts at the beginning of this String. If the starting index 1242 * is greater than the length of this String, -1 is returned. 1243 * 1244 * @param str String to find 1245 * @param fromIndex index to start the search 1246 * @return location (base 0) of the String, or -1 if not found 1247 * @throws NullPointerException if str is null 1248 */ indexOf(String str, int fromIndex)1249 public int indexOf(String str, int fromIndex) 1250 { 1251 if (fromIndex < 0) 1252 fromIndex = 0; 1253 int limit = count - str.count; 1254 for ( ; fromIndex <= limit; fromIndex++) 1255 if (regionMatches(fromIndex, str, 0, str.count)) 1256 return fromIndex; 1257 return -1; 1258 } 1259 1260 /** 1261 * Finds the last instance of a String in this String. 1262 * 1263 * @param str String to find 1264 * @return location (base 0) of the String, or -1 if not found 1265 * @throws NullPointerException if str is null 1266 */ lastIndexOf(String str)1267 public int lastIndexOf(String str) 1268 { 1269 return lastIndexOf(str, count - str.count); 1270 } 1271 1272 /** 1273 * Finds the last instance of a String in this String, starting at 1274 * a given index. If starting index is greater than the maximum valid 1275 * index, then the search begins at the end of this String. If the 1276 * starting index is less than zero, -1 is returned. 1277 * 1278 * @param str String to find 1279 * @param fromIndex index to start the search 1280 * @return location (base 0) of the String, or -1 if not found 1281 * @throws NullPointerException if str is null 1282 */ lastIndexOf(String str, int fromIndex)1283 public int lastIndexOf(String str, int fromIndex) 1284 { 1285 fromIndex = Math.min(fromIndex, count - str.count); 1286 for ( ; fromIndex >= 0; fromIndex--) 1287 if (regionMatches(fromIndex, str, 0, str.count)) 1288 return fromIndex; 1289 return -1; 1290 } 1291 1292 /** 1293 * Creates a substring of this String, starting at a specified index 1294 * and ending at the end of this String. 1295 * 1296 * @param begin index to start substring (base 0) 1297 * @return new String which is a substring of this String 1298 * @throws IndexOutOfBoundsException if begin < 0 || begin > length() 1299 * (while unspecified, this is a StringIndexOutOfBoundsException) 1300 */ substring(int begin)1301 public String substring(int begin) 1302 { 1303 return substring(begin, count); 1304 } 1305 1306 /** 1307 * Creates a substring of this String, starting at a specified index 1308 * and ending at one character before a specified index. 1309 * 1310 * @param beginIndex index to start substring (inclusive, base 0) 1311 * @param endIndex index to end at (exclusive) 1312 * @return new String which is a substring of this String 1313 * @throws IndexOutOfBoundsException if begin < 0 || end > length() 1314 * || begin > end (while unspecified, this is a 1315 * StringIndexOutOfBoundsException) 1316 */ substring(int beginIndex, int endIndex)1317 public String substring(int beginIndex, int endIndex) 1318 { 1319 if (beginIndex < 0 || endIndex > count || beginIndex > endIndex) 1320 throw new StringIndexOutOfBoundsException(); 1321 if (beginIndex == 0 && endIndex == count) 1322 return this; 1323 int len = endIndex - beginIndex; 1324 // Package constructor avoids an array copy. 1325 return new String(value, beginIndex + offset, len, 1326 (len << 2) >= value.length); 1327 } 1328 1329 /** 1330 * Creates a substring of this String, starting at a specified index 1331 * and ending at one character before a specified index. This behaves like 1332 * <code>substring(begin, end)</code>. 1333 * 1334 * @param begin index to start substring (inclusive, base 0) 1335 * @param end index to end at (exclusive) 1336 * @return new String which is a substring of this String 1337 * @throws IndexOutOfBoundsException if begin < 0 || end > length() 1338 * || begin > end 1339 * @since 1.4 1340 */ subSequence(int begin, int end)1341 public CharSequence subSequence(int begin, int end) 1342 { 1343 return substring(begin, end); 1344 } 1345 1346 /** 1347 * Concatenates a String to this String. This results in a new string unless 1348 * one of the two originals is "". 1349 * 1350 * @param str String to append to this String 1351 * @return newly concatenated String 1352 * @throws NullPointerException if str is null 1353 */ concat(String str)1354 public String concat(String str) 1355 { 1356 if (str.count == 0) 1357 return this; 1358 if (count == 0) 1359 return str; 1360 char[] newStr = new char[count + str.count]; 1361 VMSystem.arraycopy(value, offset, newStr, 0, count); 1362 VMSystem.arraycopy(str.value, str.offset, newStr, count, str.count); 1363 // Package constructor avoids an array copy. 1364 return new String(newStr, 0, newStr.length, true); 1365 } 1366 1367 /** 1368 * Replaces every instance of a character in this String with a new 1369 * character. If no replacements occur, this is returned. 1370 * 1371 * @param oldChar the old character to replace 1372 * @param newChar the new character 1373 * @return new String with all instances of oldChar replaced with newChar 1374 */ replace(char oldChar, char newChar)1375 public String replace(char oldChar, char newChar) 1376 { 1377 if (oldChar == newChar) 1378 return this; 1379 int i = count; 1380 int x = offset - 1; 1381 while (--i >= 0) 1382 if (value[++x] == oldChar) 1383 break; 1384 if (i < 0) 1385 return this; 1386 char[] newStr = toCharArray(); 1387 newStr[x - offset] = newChar; 1388 while (--i >= 0) 1389 if (value[++x] == oldChar) 1390 newStr[x - offset] = newChar; 1391 // Package constructor avoids an array copy. 1392 return new String(newStr, 0, count, true); 1393 } 1394 1395 /** 1396 * Test if this String matches a regular expression. This is shorthand for 1397 * <code>{@link Pattern}.matches(regex, this)</code>. 1398 * 1399 * @param regex the pattern to match 1400 * @return true if the pattern matches 1401 * @throws NullPointerException if regex is null 1402 * @throws PatternSyntaxException if regex is invalid 1403 * @see Pattern#matches(String, CharSequence) 1404 * @since 1.4 1405 */ matches(String regex)1406 public boolean matches(String regex) 1407 { 1408 return Pattern.matches(regex, this); 1409 } 1410 1411 /** 1412 * Replaces the first substring match of the regular expression with a 1413 * given replacement. This is shorthand for <code>{@link Pattern} 1414 * .compile(regex).matcher(this).replaceFirst(replacement)</code>. 1415 * 1416 * @param regex the pattern to match 1417 * @param replacement the replacement string 1418 * @return the modified string 1419 * @throws NullPointerException if regex or replacement is null 1420 * @throws PatternSyntaxException if regex is invalid 1421 * @see #replaceAll(String, String) 1422 * @see Pattern#compile(String) 1423 * @see Pattern#matcher(CharSequence) 1424 * @see Matcher#replaceFirst(String) 1425 * @since 1.4 1426 */ replaceFirst(String regex, String replacement)1427 public String replaceFirst(String regex, String replacement) 1428 { 1429 return Pattern.compile(regex).matcher(this).replaceFirst(replacement); 1430 } 1431 1432 /** 1433 * Replaces all matching substrings of the regular expression with a 1434 * given replacement. This is shorthand for <code>{@link Pattern} 1435 * .compile(regex).matcher(this).replaceAll(replacement)</code>. 1436 * 1437 * @param regex the pattern to match 1438 * @param replacement the replacement string 1439 * @return the modified string 1440 * @throws NullPointerException if regex or replacement is null 1441 * @throws PatternSyntaxException if regex is invalid 1442 * @see #replaceFirst(String, String) 1443 * @see Pattern#compile(String) 1444 * @see Pattern#matcher(CharSequence) 1445 * @see Matcher#replaceAll(String) 1446 * @since 1.4 1447 */ replaceAll(String regex, String replacement)1448 public String replaceAll(String regex, String replacement) 1449 { 1450 return Pattern.compile(regex).matcher(this).replaceAll(replacement); 1451 } 1452 1453 /** 1454 * Split this string around the matches of a regular expression. Each 1455 * element of the returned array is the largest block of characters not 1456 * terminated by the regular expression, in the order the matches are found. 1457 * 1458 * <p>The limit affects the length of the array. If it is positive, the 1459 * array will contain at most n elements (n - 1 pattern matches). If 1460 * negative, the array length is unlimited, but there can be trailing empty 1461 * entries. if 0, the array length is unlimited, and trailing empty entries 1462 * are discarded. 1463 * 1464 * <p>For example, splitting "boo:and:foo" yields:<br> 1465 * <table border=0> 1466 * <th><td>Regex</td> <td>Limit</td> <td>Result</td></th> 1467 * <tr><td>":"</td> <td>2</td> <td>{ "boo", "and:foo" }</td></tr> 1468 * <tr><td>":"</td> <td>t</td> <td>{ "boo", "and", "foo" }</td></tr> 1469 * <tr><td>":"</td> <td>-2</td> <td>{ "boo", "and", "foo" }</td></tr> 1470 * <tr><td>"o"</td> <td>5</td> <td>{ "b", "", ":and:f", "", "" }</td></tr> 1471 * <tr><td>"o"</td> <td>-2</td> <td>{ "b", "", ":and:f", "", "" }</td></tr> 1472 * <tr><td>"o"</td> <td>0</td> <td>{ "b", "", ":and:f" }</td></tr> 1473 * </table> 1474 * 1475 * <p>This is shorthand for 1476 * <code>{@link Pattern}.compile(regex).split(this, limit)</code>. 1477 * 1478 * @param regex the pattern to match 1479 * @param limit the limit threshold 1480 * @return the array of split strings 1481 * @throws NullPointerException if regex or replacement is null 1482 * @throws PatternSyntaxException if regex is invalid 1483 * @see Pattern#compile(String) 1484 * @see Pattern#split(CharSequence, int) 1485 * @since 1.4 1486 */ split(String regex, int limit)1487 public String[] split(String regex, int limit) 1488 { 1489 return Pattern.compile(regex).split(this, limit); 1490 } 1491 1492 /** 1493 * Split this string around the matches of a regular expression. Each 1494 * element of the returned array is the largest block of characters not 1495 * terminated by the regular expression, in the order the matches are found. 1496 * The array length is unlimited, and trailing empty entries are discarded, 1497 * as though calling <code>split(regex, 0)</code>. 1498 * 1499 * @param regex the pattern to match 1500 * @return the array of split strings 1501 * @throws NullPointerException if regex or replacement is null 1502 * @throws PatternSyntaxException if regex is invalid 1503 * @see #split(String, int) 1504 * @see Pattern#compile(String) 1505 * @see Pattern#split(CharSequence, int) 1506 * @since 1.4 1507 */ split(String regex)1508 public String[] split(String regex) 1509 { 1510 return Pattern.compile(regex).split(this, 0); 1511 } 1512 1513 /** 1514 * Convert string to lower case for a Turkish locale that requires special 1515 * handling of '\u0049' 1516 */ toLowerCaseTurkish()1517 private String toLowerCaseTurkish() 1518 { 1519 // First, see if the current string is already lower case. 1520 int i = count; 1521 int x = offset - 1; 1522 while (--i >= 0) 1523 { 1524 char ch = value[++x]; 1525 if ((ch == '\u0049') || ch != Character.toLowerCase(ch)) 1526 break; 1527 } 1528 if (i < 0) 1529 return this; 1530 1531 // Now we perform the conversion. Fortunately, there are no multi-character 1532 // lowercase expansions in Unicode 3.0.0. 1533 char[] newStr = new char[count]; 1534 VMSystem.arraycopy(value, offset, newStr, 0, x - offset); 1535 do 1536 { 1537 char ch = value[x]; 1538 // Hardcoded special case. 1539 if (ch != '\u0049') 1540 { 1541 newStr[x - offset] = Character.toLowerCase(ch); 1542 } 1543 else 1544 { 1545 newStr[x - offset] = '\u0131'; 1546 } 1547 x++; 1548 } 1549 while (--i >= 0); 1550 // Package constructor avoids an array copy. 1551 return new String(newStr, 0, count, true); 1552 } 1553 1554 /** 1555 * Lowercases this String according to a particular locale. This uses 1556 * Unicode's special case mappings, as applied to the given Locale, so the 1557 * resulting string may be a different length. 1558 * 1559 * @param loc locale to use 1560 * @return new lowercased String, or this if no characters were lowercased 1561 * @throws NullPointerException if loc is null 1562 * @see #toUpperCase(Locale) 1563 * @since 1.1 1564 */ toLowerCase(Locale loc)1565 public String toLowerCase(Locale loc) 1566 { 1567 // First, see if the current string is already lower case. 1568 1569 // Is loc turkish? String equality test is ok as Locale.language is interned 1570 if ("tr" == loc.getLanguage()) 1571 { 1572 return toLowerCaseTurkish(); 1573 } 1574 else 1575 { 1576 int i = count; 1577 int x = offset - 1; 1578 while (--i >= 0) 1579 { 1580 char ch = value[++x]; 1581 if (ch != Character.toLowerCase(ch)) 1582 break; 1583 } 1584 if (i < 0) 1585 return this; 1586 1587 // Now we perform the conversion. Fortunately, there are no 1588 // multi-character lowercase expansions in Unicode 3.0.0. 1589 char[] newStr = new char[count]; 1590 VMSystem.arraycopy(value, offset, newStr, 0, x - offset); 1591 do 1592 { 1593 char ch = value[x]; 1594 // Hardcoded special case. 1595 newStr[x - offset] = Character.toLowerCase(ch); 1596 x++; 1597 } 1598 while (--i >= 0); 1599 // Package constructor avoids an array copy. 1600 return new String(newStr, 0, count, true); 1601 } 1602 } 1603 1604 /** 1605 * Lowercases this String. This uses Unicode's special case mappings, as 1606 * applied to the platform's default Locale, so the resulting string may 1607 * be a different length. 1608 * 1609 * @return new lowercased String, or this if no characters were lowercased 1610 * @see #toLowerCase(Locale) 1611 * @see #toUpperCase() 1612 */ toLowerCase()1613 public String toLowerCase() 1614 { 1615 return toLowerCase(Locale.getDefault()); 1616 } 1617 1618 /** 1619 * Uppercase this string for a Turkish locale 1620 */ toUpperCaseTurkish()1621 private String toUpperCaseTurkish() 1622 { 1623 // First, see how many characters we have to grow by, as well as if the 1624 // current string is already upper case. 1625 int expand = 0; 1626 boolean unchanged = true; 1627 int i = count; 1628 int x = i + offset; 1629 while (--i >= 0) 1630 { 1631 char ch = value[--x]; 1632 expand += upperCaseExpansion(ch); 1633 unchanged = (unchanged && expand == 0 1634 && ch != '\u0069' 1635 && ch == Character.toUpperCase(ch)); 1636 } 1637 if (unchanged) 1638 return this; 1639 1640 // Now we perform the conversion. 1641 i = count; 1642 if (expand == 0) 1643 { 1644 char[] newStr = new char[count]; 1645 VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset)); 1646 while (--i >= 0) 1647 { 1648 char ch = value[x]; 1649 // Hardcoded special case. 1650 if (ch != '\u0069') 1651 { 1652 newStr[x - offset] = Character.toUpperCase(ch); 1653 } 1654 else 1655 { 1656 newStr[x - offset] = '\u0130'; 1657 } 1658 x++; 1659 } 1660 // Package constructor avoids an array copy. 1661 return new String(newStr, 0, count, true); 1662 } 1663 1664 // Expansion is necessary. 1665 char[] newStr = new char[count + expand]; 1666 int j = 0; 1667 while (--i >= 0) 1668 { 1669 char ch = value[x++]; 1670 // Hardcoded special case. 1671 if (ch == '\u0069') 1672 { 1673 newStr[j++] = '\u0130'; 1674 continue; 1675 } 1676 expand = upperCaseExpansion(ch); 1677 if (expand > 0) 1678 { 1679 int index = upperCaseIndex(ch); 1680 while (expand-- >= 0) 1681 newStr[j++] = upperExpand[index++]; 1682 } 1683 else 1684 newStr[j++] = Character.toUpperCase(ch); 1685 } 1686 // Package constructor avoids an array copy. 1687 return new String(newStr, 0, newStr.length, true); 1688 } 1689 1690 /** 1691 * Uppercases this String according to a particular locale. This uses 1692 * Unicode's special case mappings, as applied to the given Locale, so the 1693 * resulting string may be a different length. 1694 * 1695 * @param loc locale to use 1696 * @return new uppercased String, or this if no characters were uppercased 1697 * @throws NullPointerException if loc is null 1698 * @see #toLowerCase(Locale) 1699 * @since 1.1 1700 */ toUpperCase(Locale loc)1701 public String toUpperCase(Locale loc) 1702 { 1703 // First, see how many characters we have to grow by, as well as if the 1704 // current string is already upper case. 1705 1706 // Is loc turkish? String equality test is ok as Locale.language is interned 1707 if ("tr" == loc.getLanguage()) 1708 { 1709 return toUpperCaseTurkish(); 1710 } 1711 else 1712 { 1713 int expand = 0; 1714 boolean unchanged = true; 1715 int i = count; 1716 int x = i + offset; 1717 while (--i >= 0) 1718 { 1719 char ch = value[--x]; 1720 expand += upperCaseExpansion(ch); 1721 unchanged = (unchanged && expand == 0 1722 && ch == Character.toUpperCase(ch)); 1723 } 1724 if (unchanged) 1725 return this; 1726 1727 // Now we perform the conversion. 1728 i = count; 1729 if (expand == 0) 1730 { 1731 char[] newStr = new char[count]; 1732 VMSystem.arraycopy(value, offset, newStr, 0, count - (x - offset)); 1733 while (--i >= 0) 1734 { 1735 char ch = value[x]; 1736 newStr[x - offset] = Character.toUpperCase(ch); 1737 x++; 1738 } 1739 // Package constructor avoids an array copy. 1740 return new String(newStr, 0, count, true); 1741 } 1742 1743 // Expansion is necessary. 1744 char[] newStr = new char[count + expand]; 1745 int j = 0; 1746 while (--i >= 0) 1747 { 1748 char ch = value[x++]; 1749 expand = upperCaseExpansion(ch); 1750 if (expand > 0) 1751 { 1752 int index = upperCaseIndex(ch); 1753 while (expand-- >= 0) 1754 newStr[j++] = upperExpand[index++]; 1755 } 1756 else 1757 newStr[j++] = Character.toUpperCase(ch); 1758 } 1759 // Package constructor avoids an array copy. 1760 return new String(newStr, 0, newStr.length, true); 1761 } 1762 } 1763 /** 1764 * Uppercases this String. This uses Unicode's special case mappings, as 1765 * applied to the platform's default Locale, so the resulting string may 1766 * be a different length. 1767 * 1768 * @return new uppercased String, or this if no characters were uppercased 1769 * @see #toUpperCase(Locale) 1770 * @see #toLowerCase() 1771 */ toUpperCase()1772 public String toUpperCase() 1773 { 1774 return toUpperCase(Locale.getDefault()); 1775 } 1776 1777 /** 1778 * Trims all characters less than or equal to <code>'\u0020'</code> 1779 * (<code>' '</code>) from the beginning and end of this String. This 1780 * includes many, but not all, ASCII control characters, and all 1781 * {@link Character#isWhitespace(char)}. 1782 * 1783 * @return new trimmed String, or this if nothing trimmed 1784 */ trim()1785 public String trim() 1786 { 1787 int limit = count + offset; 1788 if (count == 0 || (value[offset] > '\u0020' 1789 && value[limit - 1] > '\u0020')) 1790 return this; 1791 int begin = offset; 1792 do 1793 if (begin == limit) 1794 return ""; 1795 while (value[begin++] <= '\u0020'); 1796 1797 int end = limit; 1798 while (value[--end] <= '\u0020') 1799 ; 1800 return substring(begin - offset - 1, end - offset + 1); 1801 } 1802 1803 /** 1804 * Returns this, as it is already a String! 1805 * 1806 * @return this 1807 */ toString()1808 public String toString() 1809 { 1810 return this; 1811 } 1812 1813 /** 1814 * Copies the contents of this String into a character array. Subsequent 1815 * changes to the array do not affect the String. 1816 * 1817 * @return character array copying the String 1818 */ toCharArray()1819 public char[] toCharArray() 1820 { 1821 char[] copy = new char[count]; 1822 VMSystem.arraycopy(value, offset, copy, 0, count); 1823 return copy; 1824 } 1825 1826 /** 1827 * Returns a String representation of an Object. This is "null" if the 1828 * object is null, otherwise it is <code>obj.toString()</code> (which 1829 * can be null). 1830 * 1831 * @param obj the Object 1832 * @return the string conversion of obj 1833 */ valueOf(Object obj)1834 public static String valueOf(Object obj) 1835 { 1836 return obj == null ? "null" : obj.toString(); 1837 } 1838 1839 /** 1840 * Returns a String representation of a character array. Subsequent 1841 * changes to the array do not affect the String. 1842 * 1843 * @param data the character array 1844 * @return a String containing the same character sequence as data 1845 * @throws NullPointerException if data is null 1846 * @see #valueOf(char[], int, int) 1847 * @see #String(char[]) 1848 */ valueOf(char[] data)1849 public static String valueOf(char[] data) 1850 { 1851 return valueOf (data, 0, data.length); 1852 } 1853 1854 /** 1855 * Returns a String representing the character sequence of the char array, 1856 * starting at the specified offset, and copying chars up to the specified 1857 * count. Subsequent changes to the array do not affect the String. 1858 * 1859 * @param data character array 1860 * @param offset position (base 0) to start copying out of data 1861 * @param count the number of characters from data to copy 1862 * @return String containing the chars from data[offset..offset+count] 1863 * @throws NullPointerException if data is null 1864 * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 1865 * || offset + count > data.length) 1866 * (while unspecified, this is a StringIndexOutOfBoundsException) 1867 * @see #String(char[], int, int) 1868 */ valueOf(char[] data, int offset, int count)1869 public static String valueOf(char[] data, int offset, int count) 1870 { 1871 return new String(data, offset, count, false); 1872 } 1873 1874 /** 1875 * Returns a String representing the character sequence of the char array, 1876 * starting at the specified offset, and copying chars up to the specified 1877 * count. Subsequent changes to the array do not affect the String. 1878 * 1879 * @param data character array 1880 * @param offset position (base 0) to start copying out of data 1881 * @param count the number of characters from data to copy 1882 * @return String containing the chars from data[offset..offset+count] 1883 * @throws NullPointerException if data is null 1884 * @throws IndexOutOfBoundsException if (offset < 0 || count < 0 1885 * || offset + count < 0 (overflow) 1886 * || offset + count < 0 (overflow) 1887 * || offset + count > data.length) 1888 * (while unspecified, this is a StringIndexOutOfBoundsException) 1889 * @see #String(char[], int, int) 1890 */ copyValueOf(char[] data, int offset, int count)1891 public static String copyValueOf(char[] data, int offset, int count) 1892 { 1893 return new String(data, offset, count, false); 1894 } 1895 1896 /** 1897 * Returns a String representation of a character array. Subsequent 1898 * changes to the array do not affect the String. 1899 * 1900 * @param data the character array 1901 * @return a String containing the same character sequence as data 1902 * @throws NullPointerException if data is null 1903 * @see #copyValueOf(char[], int, int) 1904 * @see #String(char[]) 1905 */ copyValueOf(char[] data)1906 public static String copyValueOf(char[] data) 1907 { 1908 return copyValueOf (data, 0, data.length); 1909 } 1910 1911 /** 1912 * Returns a String representing a boolean. 1913 * 1914 * @param b the boolean 1915 * @return "true" if b is true, else "false" 1916 */ valueOf(boolean b)1917 public static String valueOf(boolean b) 1918 { 1919 return b ? "true" : "false"; 1920 } 1921 1922 /** 1923 * Returns a String representing a character. 1924 * 1925 * @param c the character 1926 * @return String containing the single character c 1927 */ valueOf(char c)1928 public static String valueOf(char c) 1929 { 1930 // Package constructor avoids an array copy. 1931 return new String(new char[] { c }, 0, 1, true); 1932 } 1933 1934 /** 1935 * Returns a String representing an integer. 1936 * 1937 * @param i the integer 1938 * @return String containing the integer in base 10 1939 * @see Integer#toString(int) 1940 */ valueOf(int i)1941 public static String valueOf(int i) 1942 { 1943 // See Integer to understand why we call the two-arg variant. 1944 return Integer.toString(i, 10); 1945 } 1946 1947 /** 1948 * Returns a String representing a long. 1949 * 1950 * @param l the long 1951 * @return String containing the long in base 10 1952 * @see Long#toString(long) 1953 */ valueOf(long l)1954 public static String valueOf(long l) 1955 { 1956 return Long.toString(l); 1957 } 1958 1959 /** 1960 * Returns a String representing a float. 1961 * 1962 * @param f the float 1963 * @return String containing the float 1964 * @see Float#toString(float) 1965 */ valueOf(float f)1966 public static String valueOf(float f) 1967 { 1968 return Float.toString(f); 1969 } 1970 1971 /** 1972 * Returns a String representing a double. 1973 * 1974 * @param d the double 1975 * @return String containing the double 1976 * @see Double#toString(double) 1977 */ valueOf(double d)1978 public static String valueOf(double d) 1979 { 1980 return Double.toString(d); 1981 } 1982 1983 1984 /** @since 1.5 */ format(Locale locale, String format, Object... args)1985 public static String format(Locale locale, String format, Object... args) 1986 { 1987 Formatter f = new Formatter(locale); 1988 return f.format(format, args).toString(); 1989 } 1990 1991 /** @since 1.5 */ format(String format, Object... args)1992 public static String format(String format, Object... args) 1993 { 1994 return format(Locale.getDefault(), format, args); 1995 } 1996 1997 /** 1998 * If two Strings are considered equal, by the equals() method, 1999 * then intern() will return the same String instance. ie. 2000 * if (s1.equals(s2)) then (s1.intern() == s2.intern()). 2001 * All string literals and string-valued constant expressions 2002 * are already interned. 2003 * 2004 * @return the interned String 2005 */ intern()2006 public String intern() 2007 { 2008 return VMString.intern(this); 2009 } 2010 2011 /** 2012 * Return the number of code points between two indices in the 2013 * <code>String</code>. An unpaired surrogate counts as a 2014 * code point for this purpose. Characters outside the indicated 2015 * range are not examined, even if the range ends in the middle of a 2016 * surrogate pair. 2017 * 2018 * @param start the starting index 2019 * @param end one past the ending index 2020 * @return the number of code points 2021 * @since 1.5 2022 */ codePointCount(int start, int end)2023 public synchronized int codePointCount(int start, int end) 2024 { 2025 if (start < 0 || end > count || start > end) 2026 throw new StringIndexOutOfBoundsException(); 2027 2028 start += offset; 2029 end += offset; 2030 int count = 0; 2031 while (start < end) 2032 { 2033 char base = value[start]; 2034 if (base < Character.MIN_HIGH_SURROGATE 2035 || base > Character.MAX_HIGH_SURROGATE 2036 || start == end 2037 || start == count 2038 || value[start + 1] < Character.MIN_LOW_SURROGATE 2039 || value[start + 1] > Character.MAX_LOW_SURROGATE) 2040 { 2041 // Nothing. 2042 } 2043 else 2044 { 2045 // Surrogate pair. 2046 ++start; 2047 } 2048 ++start; 2049 ++count; 2050 } 2051 return count; 2052 } 2053 2054 /** 2055 * Helper function used to detect which characters have a multi-character 2056 * uppercase expansion. Note that this is only used in locations which 2057 * track one-to-many capitalization (java.lang.Character does not do this). 2058 * As of Unicode 3.0.0, the result is limited in the range 0 to 2, as the 2059 * longest uppercase expansion is three characters (a growth of 2 from the 2060 * lowercase character). 2061 * 2062 * @param ch the char to check 2063 * @return the number of characters to add when converting to uppercase 2064 * @see CharData#DIRECTION 2065 * @see CharData#UPPER_SPECIAL 2066 * @see #toUpperCase(Locale) 2067 */ upperCaseExpansion(char ch)2068 private static int upperCaseExpansion(char ch) 2069 { 2070 return Character.direction[0][Character.readCodePoint((int)ch) >> 7] & 3; 2071 } 2072 2073 /** 2074 * Helper function used to locate the offset in upperExpand given a 2075 * character with a multi-character expansion. The binary search is 2076 * optimized under the assumption that this method will only be called on 2077 * characters which exist in upperSpecial. 2078 * 2079 * @param ch the char to check 2080 * @return the index where its expansion begins 2081 * @see CharData#UPPER_SPECIAL 2082 * @see CharData#UPPER_EXPAND 2083 * @see #toUpperCase(Locale) 2084 */ upperCaseIndex(char ch)2085 private static int upperCaseIndex(char ch) 2086 { 2087 // Simple binary search for the correct character. 2088 int low = 0; 2089 int hi = upperSpecial.length - 2; 2090 int mid = ((low + hi) >> 2) << 1; 2091 char c = upperSpecial[mid]; 2092 while (ch != c) 2093 { 2094 if (ch < c) 2095 hi = mid - 2; 2096 else 2097 low = mid + 2; 2098 mid = ((low + hi) >> 2) << 1; 2099 c = upperSpecial[mid]; 2100 } 2101 return upperSpecial[mid + 1]; 2102 } 2103 2104 /** 2105 * Returns the value array of the given string if it is zero based or a 2106 * copy of it that is zero based (stripping offset and making length equal 2107 * to count). Used for accessing the char[]s of gnu.java.lang.CharData. 2108 * Package private for use in Character. 2109 */ zeroBasedStringValue(String s)2110 static char[] zeroBasedStringValue(String s) 2111 { 2112 char[] value; 2113 2114 if (s.offset == 0 && s.count == s.value.length) 2115 value = s.value; 2116 else 2117 { 2118 int count = s.count; 2119 value = new char[count]; 2120 VMSystem.arraycopy(s.value, s.offset, value, 0, count); 2121 } 2122 2123 return value; 2124 } 2125 2126 /** 2127 * Returns true iff this String contains the sequence of Characters 2128 * described in s. 2129 * @param s the CharSequence 2130 * @return true iff this String contains s 2131 * 2132 * @since 1.5 2133 */ contains(CharSequence s)2134 public boolean contains (CharSequence s) 2135 { 2136 return this.indexOf(s.toString()) != -1; 2137 } 2138 2139 /** 2140 * Returns a string that is this string with all instances of the sequence 2141 * represented by <code>target</code> replaced by the sequence in 2142 * <code>replacement</code>. 2143 * @param target the sequence to be replaced 2144 * @param replacement the sequence used as the replacement 2145 * @return the string constructed as above 2146 */ replace(CharSequence target, CharSequence replacement)2147 public String replace (CharSequence target, CharSequence replacement) 2148 { 2149 String targetString = target.toString(); 2150 String replaceString = replacement.toString(); 2151 int targetLength = target.length(); 2152 int replaceLength = replacement.length(); 2153 2154 int startPos = this.indexOf(targetString); 2155 CPStringBuilder result = new CPStringBuilder(this); 2156 while (startPos != -1) 2157 { 2158 // Replace the target with the replacement 2159 result.replace(startPos, startPos + targetLength, replaceString); 2160 2161 // Search for a new occurrence of the target 2162 startPos = result.indexOf(targetString, startPos + replaceLength); 2163 } 2164 return result.toString(); 2165 } 2166 2167 /** 2168 * Return the index into this String that is offset from the given index by 2169 * <code>codePointOffset</code> code points. 2170 * @param index the index at which to start 2171 * @param codePointOffset the number of code points to offset 2172 * @return the index into this String that is <code>codePointOffset</code> 2173 * code points offset from <code>index</code>. 2174 * 2175 * @throws IndexOutOfBoundsException if index is negative or larger than the 2176 * length of this string. 2177 * @throws IndexOutOfBoundsException if codePointOffset is positive and the 2178 * substring starting with index has fewer than codePointOffset code points. 2179 * @throws IndexOutOfBoundsException if codePointOffset is negative and the 2180 * substring ending with index has fewer than (-codePointOffset) code points. 2181 * @since 1.5 2182 */ offsetByCodePoints(int index, int codePointOffset)2183 public int offsetByCodePoints(int index, int codePointOffset) 2184 { 2185 if (index < 0 || index > count) 2186 throw new IndexOutOfBoundsException(); 2187 2188 return Character.offsetByCodePoints(value, offset, count, offset + index, 2189 codePointOffset); 2190 } 2191 2192 /** 2193 * Returns true if, and only if, {@link #length()} 2194 * is <code>0</code>. 2195 * 2196 * @return true if the length of the string is zero. 2197 * @since 1.6 2198 */ isEmpty()2199 public boolean isEmpty() 2200 { 2201 return count == 0; 2202 } 2203 2204 } 2205