Overview Package Class Use Source Tree Index Deprecated About
GNU Classpath (0.95)
Frames | No Frames

Source for java.lang.String

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

AltStyle によって変換されたページ (->オリジナル) /